@@ -10,6 +10,7 @@ import filetype import httpx import tiktoken from PIL import Image +from PIL.Image import DecompressionBombError from django.core.files import File from django.core.files.images import get_image_dimensions @@ -19,6 +20,7 @@ from ml_model.exceptions import ( CorruptedFileError, FileExtensionNotSupported, GenerationException, + ImageTooLargeError, RequestBlocked, ) from ml_model.services.base import SimpleService @@ -53,6 +55,7 @@ class Gptimage(SimpleService): '1024x1536': 1372, }, } + MAX_PIXELS = 178956970 OPTIMIZATION_PROMPT = """ Clean composition and consistent perspective. Natural color harmony, realistic texture detail, and sharp subject focus. @@ -99,9 +102,14 @@ class Gptimage(SimpleService): if kind.extension.upper() not in (extensions := ['PNG', 'JPG', 'JPEG', 'WEBP']): raise FileExtensionNotSupported(extensions) file.seek(0) - w, h = get_image_dimensions(file) + try: + w, h = get_image_dimensions(file) + except DecompressionBombError: + raise ImageTooLargeError(self.MAX_PIXELS) if not w or not h: raise CorruptedFileError + if w * h > self.MAX_PIXELS: + raise ImageTooLargeError(self.MAX_PIXELS) normalized_image = BytesIO(file_bytes) if kind.extension.upper() != 'PNG': with Image.open(normalized_image) as source_image: @@ -26,6 +26,7 @@ from ml_model.exceptions import ( FileTooLargeError, FileUploadUnsupported, ImageAnalysisError, + ImageTooLargeError, InvalidParameterError, ModelVersionNotAvailable, PaidPlanRequiredError, @@ -182,6 +183,7 @@ class MessagesAPIView(APIView): UnrecognizedFileError, InvalidParameterError, ModelVersionNotAvailable, + ImageTooLargeError, ) as exc: return Response({'detail': f'{exc}'}, status=HTTP_400_BAD_REQUEST) except TemplateNotFound as exc: @@ -22,6 +22,7 @@ from ml_model.exceptions import ( FileTooLargeError, ImageAnalysisError, ImageContentNotFound, + ImageTooLargeError, InvalidParameterError, InvalidStyleCombinationError, ModelCouldNotInterpretPrompt, @@ -206,6 +207,7 @@ class MediaAPIView(APIView): UnrecognizedFileError, FaceNotFoundError, RealPersonDetectedError, + ImageTooLargeError, ) as exc: return Response({'detail': f'{exc}'}, status=HTTP_400_BAD_REQUEST) except Exception as exc: