/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d R A W I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadRAWImage() reads an image of raw samples and returns it. It allocates % the memory necessary for the new Image structure and returns a pointer to % the new image. % % The format of the ReadRAWImage method is: % % Image *ReadRAWImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadRAWImage(const ImageInfo *image_info,ExceptionInfo *exception) { const unsigned char *pixels; Image *canvas_image, *image; MagickBooleanType status; MagickOffsetType scene; QuantumInfo *quantum_info; QuantumType quantum_type; size_t length; ssize_t count, y; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } if (DiscardBlobBytes(image,image->offset) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); /* Create virtual canvas to support cropping (i.e. image.gray[100x100+10+20]). */ canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse, exception); (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod); quantum_type=GrayQuantum; quantum_info=AcquireQuantumInfo(image_info,canvas_image); if (quantum_info == (QuantumInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); pixels=(const unsigned char *) NULL; if (image_info->number_scenes != 0) while (image->scene < image_info->scene) { /* Skip to next image. */ image->scene++; length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); for (y=0; y < (ssize_t) image->rows; y++) { pixels=(const unsigned char *) ReadBlobStream(image,length, GetQuantumPixels(quantum_info),&count); if (count != (ssize_t) length) break; } } scene=0; count=0; length=0; do { /* Read pixels to virtual canvas image then push to image. */ if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; status=SetImageExtent(image,image->columns,image->rows); if (status == MagickFalse) { InheritException(exception,&image->exception); return(DestroyImageList(image)); } if (scene == 0) { length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); pixels=(const unsigned char *) ReadBlobStream(image,length, GetQuantumPixels(quantum_info),&count); } for (y=0; y < (ssize_t) image->extract_info.height; y++) { register const PixelPacket *magick_restrict p; register PixelPacket *magick_restrict q; register ssize_t x; if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,quantum_info, quantum_type,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, image->columns,1,exception); q=QueueAuthenticPixels(image,0,y-image->extract_info.y,image->columns, 1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelRed(q,GetPixelRed(p)); SetPixelGreen(q,GetPixelGreen(p)); SetPixelBlue(q,GetPixelBlue(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } pixels=(const unsigned char *) ReadBlobStream(image,length, GetQuantumPixels(quantum_info),&count); } SetQuantumImageType(image,quantum_type); /* Proceed to next image. */ if (image_info->number_scenes != 0) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; if (count == (ssize_t) length) { /* Allocate next image structure. */ AcquireNextImage(image_info,image); if (GetNextImageInList(image) == (Image *) NULL) { image=DestroyImageList(image); return((Image *) NULL); } image=SyncNextImageInList(image); status=SetImageProgress(image,LoadImagesTag,TellBlob(image), GetBlobSize(image)); if (status == MagickFalse) break; } scene++; } while (count == (ssize_t) length); quantum_info=DestroyQuantumInfo(quantum_info); InheritException(&image->exception,&canvas_image->exception); canvas_image=DestroyImage(canvas_image); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d P E S I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadPESImage() reads a Brother PES image file and returns it. It allocates % the memory necessary for the new Image structure and returns a pointer to % the new image. % % The format of the ReadPESImage method is: % % image=ReadPESImage(image_info) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadPESImage(const ImageInfo *image_info,ExceptionInfo *exception) { char filename[MaxTextExtent]; FILE *file; Image *image; ImageInfo *read_info; int delta_x, delta_y, j, unique_file, x, y; MagickBooleanType status; PESBlockInfo blocks[256]; PointInfo *stitches; SegmentInfo bounds; register ssize_t i; size_t number_blocks, number_colors, number_stitches; ssize_t count, offset; unsigned char magick[4], version[4]; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Verify PES identifier. */ count=ReadBlob(image,4,magick); if ((count != 4) || (LocaleNCompare((char *) magick,"#PES",4) != 0)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); count=ReadBlob(image,4,version); offset=(int) ReadBlobLSBLong(image); if (DiscardBlobBytes(image,offset+36) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); if (EOFBlob(image) != MagickFalse) ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile"); /* Get PES colors. */ number_colors=(size_t) ReadBlobByte(image)+1; for (i=0; i < (ssize_t) number_colors; i++) { j=(int) ReadBlobByte(image); blocks[i].color=PESColor+(j < 0 ? 0 : j); blocks[i].offset=0; } for ( ; i < 256L; i++) blocks[i].offset=0; if (DiscardBlobBytes(image,532L-number_colors-21) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); if (EOFBlob(image) != MagickFalse) ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile"); /* Stitch away. */ number_stitches=64; stitches=(PointInfo *) AcquireQuantumMemory(number_stitches, sizeof(*stitches)); if (stitches == (PointInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); bounds.x1=65535.0; bounds.y1=65535.0; bounds.x2=(-65535.0); bounds.y2=(-65535.0); i=0; j=0; delta_x=0; delta_y=0; while (EOFBlob(image) != EOF) { x=(int) ReadBlobByte(image); y=(int) ReadBlobByte(image); if ((x == 0xff) && (y == 0)) break; if ((x == 254) && (y == 176)) { /* Start a new stitch block. */ j++; blocks[j].offset=(ssize_t) i; if (j >= 256) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); (void) ReadBlobByte(image); continue; } if ((x & 0x80) == 0) { /* Normal stitch. */ if ((x & 0x40) != 0) x-=0x80; } else { /* Jump stitch. */ x=((x & 0x0f) << 8)+y; if ((x & 0x800) != 0) x-=0x1000; y=ReadBlobByte(image); } if ((y & 0x80) == 0) { /* Normal stitch. */ if ((y & 0x40) != 0) y-=0x80; } else { /* Jump stitch. */ y=((y & 0x0f) << 8)+ReadBlobByte(image); if ((y & 0x800) != 0) y-=0x1000; } /* Note stitch (x,y). */ x+=delta_x; y+=delta_y; delta_x=x; delta_y=y; stitches[i].x=(double) x; stitches[i].y=(double) y; if ((double) x < bounds.x1) bounds.x1=(double) x; if ((double) x > bounds.x2) bounds.x2=(double) x; if ((double) y < bounds.y1) bounds.y1=(double) y; if ((double) y > bounds.y2) bounds.y2=(double) y; i++; if (i >= (ssize_t) number_stitches) { /* Make room for more stitches. */ number_stitches<<=1; stitches=(PointInfo *) ResizeQuantumMemory(stitches,(size_t) number_stitches,sizeof(*stitches)); if (stitches == (PointInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } } j++; blocks[j].offset=(ssize_t) i; number_blocks=(size_t) j; /* Write stitches as SVG file. */ file=(FILE *) NULL; unique_file=AcquireUniqueFileResource(filename); if (unique_file != -1) file=fdopen(unique_file,"wb"); if ((unique_file == -1) || (file == (FILE *) NULL)) ThrowImageException(FileOpenError,"UnableToCreateTemporaryFile"); (void) FormatLocaleFile(file,"<?xml version=\"1.0\"?>\n"); (void) FormatLocaleFile(file,"<svg xmlns=\"http://www.w3.org/2000/svg\" " "xlink=\"http://www.w3.org/1999/xlink\" " "ev=\"http://www.w3.org/2001/xml-events\" version=\"1.1\" " "baseProfile=\"full\" width=\"%g\" height=\"%g\">\n",bounds.x2-bounds.x1, bounds.y2-bounds.y1); for (i=0; i < (ssize_t) number_blocks; i++) { offset=blocks[i].offset; (void) FormatLocaleFile(file," <path stroke=\"#%02x%02x%02x\" " "fill=\"none\" d=\"M %g %g",blocks[i].color->red,blocks[i].color->green, blocks[i].color->blue,stitches[offset].x-bounds.x1, stitches[offset].y-bounds.y1); for (j=1; j < (ssize_t) (blocks[i+1].offset-offset); j++) (void) FormatLocaleFile(file," L %g %g",stitches[offset+j].x-bounds.x1, stitches[offset+j].y-bounds.y1); (void) FormatLocaleFile(file,"\"/>\n"); } (void) FormatLocaleFile(file,"</svg>\n"); (void) fclose(file); (void) CloseBlob(image); image=DestroyImage(image); /* Read SVG file. */ read_info=CloneImageInfo(image_info); SetImageInfoBlob(read_info,(void *) NULL,0); (void) FormatLocaleString(read_info->filename,MaxTextExtent,"svg:%s", filename); image=ReadImage(read_info,exception); if (image != (Image *) NULL) { (void) CopyMagickString(image->filename,image_info->filename, MaxTextExtent); (void) CopyMagickString(image->magick_filename,image_info->filename, MaxTextExtent); (void) CopyMagickString(image->magick,"PES",MaxTextExtent); } read_info=DestroyImageInfo(read_info); (void) RelinquishUniqueFileResource(filename); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d Y U V I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadYUVImage() reads an image with digital YUV (CCIR 601 4:1:1, plane % or partition interlaced, or 4:2:2 plane, partition interlaced or % noninterlaced) bytes and returns it. It allocates the memory necessary % for the new Image structure and returns a pointer to the new image. % % The format of the ReadYUVImage method is: % % Image *ReadYUVImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadYUVImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *chroma_image, *image, *resize_image; InterlaceType interlace; MagickBooleanType status; register const PixelPacket *chroma_pixels; register ssize_t x; register PixelPacket *q; register unsigned char *p; ssize_t count, horizontal_factor, vertical_factor, y; size_t quantum; unsigned char *scanline; /* Allocate image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); status=SetImageExtent(image,image->columns,image->rows); if (status == MagickFalse) { InheritException(exception,&image->exception); return(DestroyImageList(image)); } quantum=(size_t) (image->depth <= 8 ? 1 : 2); interlace=image_info->interlace; horizontal_factor=2; vertical_factor=2; if (image_info->sampling_factor != (char *) NULL) { GeometryInfo geometry_info; MagickStatusType flags; flags=ParseGeometry(image_info->sampling_factor,&geometry_info); horizontal_factor=(ssize_t) geometry_info.rho; vertical_factor=(ssize_t) geometry_info.sigma; if ((flags & SigmaValue) == 0) vertical_factor=horizontal_factor; if ((horizontal_factor != 1) && (horizontal_factor != 2) && (vertical_factor != 1) && (vertical_factor != 2)) ThrowReaderException(CorruptImageError,"UnexpectedSamplingFactor"); } if ((interlace == UndefinedInterlace) || ((interlace == NoInterlace) && (vertical_factor == 2))) { interlace=NoInterlace; /* CCIR 4:2:2 */ if (vertical_factor == 2) interlace=PlaneInterlace; /* CCIR 4:1:1 */ } if (interlace != PartitionInterlace) { /* Open image file. */ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); } /* Allocate memory for a scanline. */ if (interlace == NoInterlace) scanline=(unsigned char *) AcquireQuantumMemory((size_t) 2UL* image->columns+2UL,quantum*sizeof(*scanline)); else scanline=(unsigned char *) AcquireQuantumMemory(image->columns, quantum*sizeof(*scanline)); if (scanline == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); do { chroma_image=CloneImage(image,(image->columns + horizontal_factor - 1) / horizontal_factor, (image->rows + vertical_factor - 1) / vertical_factor, MagickTrue,exception); if (chroma_image == (Image *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); /* Convert raster image to pixel packets. */ if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; status=SetImageExtent(image,image->columns,image->rows); if (status == MagickFalse) { InheritException(exception,&image->exception); return(DestroyImageList(image)); } if (interlace == PartitionInterlace) { AppendImageFormat("Y",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } } for (y=0; y < (ssize_t) image->rows; y++) { register PixelPacket *chroma_pixels; if (interlace == NoInterlace) { if ((y > 0) || (GetPreviousImageInList(image) == (Image *) NULL)) (void) ReadBlob(image,(size_t) (2*quantum*image->columns),scanline); p=scanline; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; chroma_pixels=QueueAuthenticPixels(chroma_image,0,y, chroma_image->columns,1,exception); if (chroma_pixels == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x+=2) { SetPixelRed(chroma_pixels,0); if (quantum == 1) SetPixelGreen(chroma_pixels,ScaleCharToQuantum(*p++)); else { SetPixelGreen(chroma_pixels,ScaleShortToQuantum(((*p) << 8) | *(p+1))); p+=2; } if (quantum == 1) SetPixelRed(q,ScaleCharToQuantum(*p++)); else { SetPixelRed(q,ScaleShortToQuantum(((*p) << 8) | *(p+1))); p+=2; } SetPixelGreen(q,0); SetPixelBlue(q,0); q++; SetPixelGreen(q,0); SetPixelBlue(q,0); if (quantum == 1) SetPixelBlue(chroma_pixels,ScaleCharToQuantum(*p++)); else { SetPixelBlue(chroma_pixels,ScaleShortToQuantum(((*p) << 8) | *(p+1))); p+=2; } if (quantum == 1) SetPixelRed(q,ScaleCharToQuantum(*p++)); else { SetPixelRed(q,ScaleShortToQuantum(((*p) << 8) | *(p+1))); p+=2; } chroma_pixels++; q++; } } else { if ((y > 0) || (GetPreviousImageInList(image) == (Image *) NULL)) (void) ReadBlob(image,(size_t) quantum*image->columns,scanline); p=scanline; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { if (quantum == 1) SetPixelRed(q,ScaleCharToQuantum(*p++)); else { SetPixelRed(q,ScaleShortToQuantum(((*p) << 8) | *(p+1))); p+=2; } SetPixelGreen(q,0); SetPixelBlue(q,0); q++; } } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (interlace == NoInterlace) if (SyncAuthenticPixels(chroma_image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } if (interlace == PartitionInterlace) { (void) CloseBlob(image); AppendImageFormat("U",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } } if (interlace != NoInterlace) { for (y=0; y < (ssize_t) chroma_image->rows; y++) { (void) ReadBlob(image,(size_t) quantum*chroma_image->columns,scanline); p=scanline; q=QueueAuthenticPixels(chroma_image,0,y,chroma_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) chroma_image->columns; x++) { SetPixelRed(q,0); if (quantum == 1) SetPixelGreen(q,ScaleCharToQuantum(*p++)); else { SetPixelGreen(q,ScaleShortToQuantum(((*p) << 8) | *(p+1))); p+=2; } SetPixelBlue(q,0); q++; } if (SyncAuthenticPixels(chroma_image,exception) == MagickFalse) break; } if (interlace == PartitionInterlace) { (void) CloseBlob(image); AppendImageFormat("V",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } } for (y=0; y < (ssize_t) chroma_image->rows; y++) { (void) ReadBlob(image,(size_t) quantum*chroma_image->columns,scanline); p=scanline; q=GetAuthenticPixels(chroma_image,0,y,chroma_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) chroma_image->columns; x++) { if (quantum == 1) SetPixelBlue(q,ScaleCharToQuantum(*p++)); else { SetPixelBlue(q,ScaleShortToQuantum(((*p) << 8) | *(p+1))); p+=2; } q++; } if (SyncAuthenticPixels(chroma_image,exception) == MagickFalse) break; } } /* Scale image. */ resize_image=ResizeImage(chroma_image,image->columns,image->rows, TriangleFilter,1.0,exception); chroma_image=DestroyImage(chroma_image); if (resize_image == (Image *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (y=0; y < (ssize_t) image->rows; y++) { q=GetAuthenticPixels(image,0,y,image->columns,1,exception); chroma_pixels=GetVirtualPixels(resize_image,0,y,resize_image->columns,1, &resize_image->exception); if ((q == (PixelPacket *) NULL) || (chroma_pixels == (const PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelGreen(q,GetPixelGreen(chroma_pixels)); SetPixelBlue(q,GetPixelBlue(chroma_pixels)); chroma_pixels++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } resize_image=DestroyImage(resize_image); SetImageColorspace(image,YCbCrColorspace); if (interlace == PartitionInterlace) (void) CopyMagickString(image->filename,image_info->filename, MaxTextExtent); if (EOFBlob(image) != MagickFalse) { ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); break; } /* Proceed to next image. */ if (image_info->number_scenes != 0) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; if (interlace == NoInterlace) count=ReadBlob(image,(size_t) (2*quantum*image->columns),scanline); else count=ReadBlob(image,(size_t) quantum*image->columns,scanline); if (count != 0) { /* Allocate next image structure. */ AcquireNextImage(image_info,image); if (GetNextImageInList(image) == (Image *) NULL) { image=DestroyImageList(image); return((Image *) NULL); } image=SyncNextImageInList(image); status=SetImageProgress(image,LoadImagesTag,TellBlob(image), GetBlobSize(image)); if (status == MagickFalse) break; } } while (count != 0); scanline=(unsigned char *) RelinquishMagickMemory(scanline); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d X C F I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadXCFImage() reads a GIMP (GNU Image Manipulation Program) image % file and returns it. It allocates the memory necessary for the new Image % structure and returns a pointer to the new image. % % The format of the ReadXCFImage method is: % % image=ReadXCFImage(image_info) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % % */ static Image *ReadXCFImage(const ImageInfo *image_info,ExceptionInfo *exception) { char magick[14]; Image *image; int foundPropEnd = 0; MagickBooleanType status; MagickOffsetType offset; register ssize_t i; size_t length; ssize_t count; size_t image_type; XCFDocInfo doc_info; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } count=ReadBlob(image,14,(unsigned char *) magick); if ((count == 0) || (LocaleNCompare((char *) magick,"gimp xcf",8) != 0)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); (void) ResetMagickMemory(&doc_info,0,sizeof(XCFDocInfo)); doc_info.exception=exception; doc_info.width=ReadBlobMSBLong(image); doc_info.height=ReadBlobMSBLong(image); if ((doc_info.width > 262144) || (doc_info.height > 262144)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); doc_info.image_type=ReadBlobMSBLong(image); /* Initialize image attributes. */ image->columns=doc_info.width; image->rows=doc_info.height; image_type=doc_info.image_type; doc_info.file_size=GetBlobSize(image); image->compression=NoCompression; image->depth=8; if (image_type == GIMP_RGB) image->colorspace=RGBColorspace; else if (image_type == GIMP_GRAY) image->colorspace=GRAYColorspace; else if (image_type == GIMP_INDEXED) ThrowReaderException(CoderError,"ColormapTypeNotSupported"); (void) SetImageBackgroundColor(image); image->matte=MagickTrue; /* Read properties. */ while ((foundPropEnd == MagickFalse) && (EOFBlob(image) == MagickFalse)) { PropType prop_type = (PropType) ReadBlobMSBLong(image); size_t prop_size = ReadBlobMSBLong(image); switch (prop_type) { case PROP_END: foundPropEnd=1; break; case PROP_COLORMAP: { /* Cannot rely on prop_size here--the value is set incorrectly by some Gimp versions. */ size_t num_colours = ReadBlobMSBLong(image); if (DiscardBlobBytes(image,3*num_colours) == MagickFalse) ThrowFileException(&image->exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); /* if (info->file_version == 0) { gint i; g_message (_("XCF warning: version 0 of XCF file format\n" "did not save indexed colormaps correctly.\n" "Substituting grayscale map.")); info->cp += xcf_read_int32 (info->fp, (guint32*) &gimage->num_cols, 1); gimage->cmap = g_new (guchar, gimage->num_cols*3); xcf_seek_pos (info, info->cp + gimage->num_cols); for (i = 0; i<gimage->num_cols; i++) { gimage->cmap[i*3+0] = i; gimage->cmap[i*3+1] = i; gimage->cmap[i*3+2] = i; } } else { info->cp += xcf_read_int32 (info->fp, (guint32*) &gimage->num_cols, 1); gimage->cmap = g_new (guchar, gimage->num_cols*3); info->cp += xcf_read_int8 (info->fp, (guint8*) gimage->cmap, gimage->num_cols*3); } */ break; } case PROP_COMPRESSION: { doc_info.compression = ReadBlobByte(image); if ((doc_info.compression != COMPRESS_NONE) && (doc_info.compression != COMPRESS_RLE) && (doc_info.compression != COMPRESS_ZLIB) && (doc_info.compression != COMPRESS_FRACTAL)) ThrowReaderException(CorruptImageError,"UnrecognizedImageCompression"); } break; case PROP_GUIDES: { /* just skip it - we don't care about guides */ if (DiscardBlobBytes(image,prop_size) == MagickFalse) ThrowFileException(&image->exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); } break; case PROP_RESOLUTION: { /* float xres = (float) */ (void) ReadBlobMSBLong(image); /* float yres = (float) */ (void) ReadBlobMSBLong(image); /* if (xres < GIMP_MIN_RESOLUTION || xres > GIMP_MAX_RESOLUTION || yres < GIMP_MIN_RESOLUTION || yres > GIMP_MAX_RESOLUTION) { g_message ("Warning, resolution out of range in XCF file"); xres = gimage->gimp->config->default_xresolution; yres = gimage->gimp->config->default_yresolution; } */ /* BOGUS: we don't write these yet because we aren't reading them properly yet :( image->x_resolution = xres; image->y_resolution = yres; */ } break; case PROP_TATTOO: { /* we need to read it, even if we ignore it */ /*size_t tattoo_state = */ (void) ReadBlobMSBLong(image); } break; case PROP_PARASITES: { /* BOGUS: we may need these for IPTC stuff */ if (DiscardBlobBytes(image,prop_size) == MagickFalse) ThrowFileException(&image->exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); /* gssize_t base = info->cp; GimpParasite *p; while (info->cp - base < prop_size) { p = xcf_load_parasite (info); gimp_image_parasite_attach (gimage, p); gimp_parasite_free (p); } if (info->cp - base != prop_size) g_message ("Error detected while loading an image's parasites"); */ } break; case PROP_UNIT: { /* BOGUS: ignore for now... */ /*size_t unit = */ (void) ReadBlobMSBLong(image); } break; case PROP_PATHS: { /* BOGUS: just skip it for now */ if (DiscardBlobBytes(image,prop_size) == MagickFalse) ThrowFileException(&image->exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); /* PathList *paths = xcf_load_bzpaths (gimage, info); gimp_image_set_paths (gimage, paths); */ } break; case PROP_USER_UNIT: { char unit_string[1000]; /*BOGUS: ignored for now */ /*float factor = (float) */ (void) ReadBlobMSBLong(image); /* size_t digits = */ (void) ReadBlobMSBLong(image); for (i=0; i<5; i++) (void) ReadBlobStringWithLongSize(image, unit_string, sizeof(unit_string)); } break; default: { int buf[16]; ssize_t amount; /* read over it... */ while ((prop_size > 0) && (EOFBlob(image) == MagickFalse)) { amount=(ssize_t) MagickMin(16, prop_size); amount=(ssize_t) ReadBlob(image,(size_t) amount,(unsigned char *) &buf); if (!amount) ThrowReaderException(CorruptImageError,"CorruptImage"); prop_size -= (size_t) MagickMin(16,(size_t) amount); } } break; } } if (foundPropEnd == MagickFalse) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) { ; /* do nothing, were just pinging! */ } else { int current_layer = 0, foundAllLayers = MagickFalse, number_layers = 0; MagickOffsetType oldPos=TellBlob(image); XCFLayerInfo *layer_info; /* the read pointer */ do { ssize_t offset = (int) ReadBlobMSBLong(image); if (offset == 0) foundAllLayers=MagickTrue; else number_layers++; if (EOFBlob(image) != MagickFalse) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } } while (foundAllLayers == MagickFalse); offset=SeekBlob(image,oldPos,SEEK_SET); /* restore the position! */ if (offset < 0) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); /* allocate our array of layer info blocks */ length=(size_t) number_layers; layer_info=(XCFLayerInfo *) AcquireQuantumMemory(length, sizeof(*layer_info)); if (layer_info == (XCFLayerInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); (void) ResetMagickMemory(layer_info,0,number_layers*sizeof(XCFLayerInfo)); for ( ; ; ) { MagickBooleanType layer_ok; MagickOffsetType offset, saved_pos; /* read in the offset of the next layer */ offset=(MagickOffsetType) ReadBlobMSBLong(image); /* if the offset is 0 then we are at the end * of the layer list. */ if (offset == 0) break; /* save the current position as it is where the * next layer offset is stored. */ saved_pos=TellBlob(image); /* seek to the layer offset */ offset=SeekBlob(image,offset,SEEK_SET); /* read in the layer */ layer_ok=ReadOneLayer(image,&doc_info,&layer_info[current_layer]); if (layer_ok == MagickFalse) { int j; for (j=0; j < current_layer; j++) layer_info[j].image=DestroyImage(layer_info[j].image); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } /* restore the saved position so we'll be ready to * read the next offset. */ offset=SeekBlob(image, saved_pos, SEEK_SET); current_layer++; } if (number_layers == 1) { /* Composite the layer data onto the main image, dispose the layer. */ (void) CompositeImage(image,OverCompositeOp,layer_info[0].image, layer_info[0].offset_x,layer_info[0].offset_y); layer_info[0].image =DestroyImage( layer_info[0].image); } else { #if 0 { /* NOTE: XCF layers are REVERSED from composite order! */ signed int j; for (j=number_layers-1; j>=0; j--) { /* BOGUS: need to consider layer blending modes!! */ if ( layer_info[j].visible ) { /* only visible ones, please! */ CompositeImage(image, OverCompositeOp, layer_info[j].image, layer_info[j].offset_x, layer_info[j].offset_y ); layer_info[j].image =DestroyImage( layer_info[j].image ); /* Bob says that if we do this, we'll get REAL gray images! */ if ( image_type == GIMP_GRAY ) { QuantizeInfo qi; GetQuantizeInfo(&qi); qi.colorspace = GRAYColorspace; QuantizeImage( &qi, layer_info[j].image ); } } } } #else { /* NOTE: XCF layers are REVERSED from composite order! */ signed int j; /* first we copy the last layer on top of the main image */ (void) CompositeImage(image,CopyCompositeOp, layer_info[number_layers-1].image, layer_info[number_layers-1].offset_x, layer_info[number_layers-1].offset_y); layer_info[number_layers-1].image=DestroyImage( layer_info[number_layers-1].image); /* now reverse the order of the layers as they are put into subimages */ j=number_layers-2; image->next=layer_info[j].image; layer_info[j].image->previous=image; layer_info[j].image->page.x=layer_info[j].offset_x; layer_info[j].image->page.y=layer_info[j].offset_y; layer_info[j].image->page.width=layer_info[j].width; layer_info[j].image->page.height=layer_info[j].height; for (j=number_layers-3; j>=0; j--) { if (j > 0) layer_info[j].image->next=layer_info[j-1].image; if (j < (number_layers-1)) layer_info[j].image->previous=layer_info[j+1].image; layer_info[j].image->page.x=layer_info[j].offset_x; layer_info[j].image->page.y=layer_info[j].offset_y; layer_info[j].image->page.width=layer_info[j].width; layer_info[j].image->page.height=layer_info[j].height; } } #endif } layer_info=(XCFLayerInfo *) RelinquishMagickMemory(layer_info); #if 0 /* BOGUS: do we need the channels?? */ while (MagickTrue) { /* read in the offset of the next channel */ info->cp += xcf_read_int32 (info->fp, &offset, 1); /* if the offset is 0 then we are at the end * of the channel list. */ if (offset == 0) break; /* save the current position as it is where the * next channel offset is stored. */ saved_pos = info->cp; /* seek to the channel offset */ xcf_seek_pos (info, offset); /* read in the layer */ channel = xcf_load_channel (info, gimage); if (channel == 0) goto error; num_successful_elements++; /* add the channel to the image if its not the selection */ if (channel != gimage->selection_mask) gimp_image_add_channel (gimage, channel, -1); /* restore the saved position so we'll be ready to * read the next offset. */ xcf_seek_pos (info, saved_pos); } #endif } (void) CloseBlob(image); if (image_type == GIMP_GRAY) image->type=GrayscaleType; return(GetFirstImageInList(image)); }
static MagickBooleanType ReadOneLayer(Image* image,XCFDocInfo* inDocInfo, XCFLayerInfo *outLayer ) { MagickOffsetType offset; unsigned int foundPropEnd = 0; size_t hierarchy_offset, layer_mask_offset; /* clear the block! */ (void) ResetMagickMemory( outLayer, 0, sizeof( XCFLayerInfo ) ); /* read in the layer width, height, type and name */ outLayer->width = ReadBlobMSBLong(image); outLayer->height = ReadBlobMSBLong(image); outLayer->type = ReadBlobMSBLong(image); (void) ReadBlobStringWithLongSize(image, outLayer->name, sizeof(outLayer->name)); /* allocate the image for this layer */ outLayer->image=CloneImage(image,outLayer->width, outLayer->height,MagickTrue, &image->exception); if (outLayer->image == (Image *) NULL) return MagickFalse; /* read the layer properties! */ foundPropEnd = 0; while ( (foundPropEnd == MagickFalse) && (EOFBlob(image) == MagickFalse) ) { PropType prop_type = (PropType) ReadBlobMSBLong(image); size_t prop_size = ReadBlobMSBLong(image); switch (prop_type) { case PROP_END: foundPropEnd = 1; break; case PROP_ACTIVE_LAYER: outLayer->active = 1; break; case PROP_FLOATING_SELECTION: outLayer->floating_offset = ReadBlobMSBLong(image); break; case PROP_OPACITY: outLayer->opacity = ReadBlobMSBLong(image); break; case PROP_VISIBLE: outLayer->visible = ReadBlobMSBLong(image); break; case PROP_LINKED: outLayer->linked = ReadBlobMSBLong(image); break; case PROP_PRESERVE_TRANSPARENCY: outLayer->preserve_trans = ReadBlobMSBLong(image); break; case PROP_APPLY_MASK: outLayer->apply_mask = ReadBlobMSBLong(image); break; case PROP_EDIT_MASK: outLayer->edit_mask = ReadBlobMSBLong(image); break; case PROP_SHOW_MASK: outLayer->show_mask = ReadBlobMSBLong(image); break; case PROP_OFFSETS: outLayer->offset_x = (int) ReadBlobMSBLong(image); outLayer->offset_y = (int) ReadBlobMSBLong(image); break; case PROP_MODE: outLayer->mode = ReadBlobMSBLong(image); break; case PROP_TATTOO: outLayer->preserve_trans = ReadBlobMSBLong(image); break; case PROP_PARASITES: { if (DiscardBlobBytes(image,prop_size) == MagickFalse) ThrowFileException(&image->exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); /* ssize_t base = info->cp; GimpParasite *p; while (info->cp - base < prop_size) { p = xcf_load_parasite(info); gimp_drawable_parasite_attach(GIMP_DRAWABLE(layer), p); gimp_parasite_free(p); } if (info->cp - base != prop_size) g_message ("Error detected while loading a layer's parasites"); */ } break; default: /* g_message ("unexpected/unknown layer property: %d (skipping)", prop_type); */ { int buf[16]; ssize_t amount; /* read over it... */ while ((prop_size > 0) && (EOFBlob(image) == MagickFalse)) { amount = (ssize_t) MagickMin(16, prop_size); amount = ReadBlob(image, (size_t) amount, (unsigned char *) &buf); if (!amount) ThrowBinaryException(CorruptImageError,"CorruptImage", image->filename); prop_size -= (size_t) MagickMin(16, (size_t) amount); } } break; } } if (foundPropEnd == MagickFalse) return(MagickFalse); /* clear the image based on the layer opacity */ outLayer->image->background_color.opacity= ScaleCharToQuantum((unsigned char) (255-outLayer->opacity)); (void) SetImageBackgroundColor(outLayer->image); /* set the compositing mode */ outLayer->image->compose = GIMPBlendModeToCompositeOperator( outLayer->mode ); if ( outLayer->visible == MagickFalse ) { /* BOGUS: should really be separate member var! */ outLayer->image->compose = NoCompositeOp; } /* read the hierarchy and layer mask offsets */ hierarchy_offset = ReadBlobMSBLong(image); layer_mask_offset = ReadBlobMSBLong(image); /* read in the hierarchy */ offset=SeekBlob(image, (MagickOffsetType) hierarchy_offset, SEEK_SET); if (offset < 0) (void) ThrowMagickException(&image->exception,GetMagickModule(), CorruptImageError,"InvalidImageHeader","`%s'",image->filename); if (load_hierarchy (image, inDocInfo, outLayer) == 0) return(MagickFalse); /* read in the layer mask */ if (layer_mask_offset != 0) { offset=SeekBlob(image, (MagickOffsetType) layer_mask_offset, SEEK_SET); #if 0 /* BOGUS: support layer masks! */ layer_mask = xcf_load_layer_mask (info, gimage); if (layer_mask == 0) goto error; /* set the offsets of the layer_mask */ GIMP_DRAWABLE (layer_mask)->offset_x = GIMP_DRAWABLE (layer)->offset_x; GIMP_DRAWABLE (layer_mask)->offset_y = GIMP_DRAWABLE (layer)->offset_y; gimp_layer_add_mask (layer, layer_mask, MagickFalse); layer->mask->apply_mask = apply_mask; layer->mask->edit_mask = edit_mask; layer->mask->show_mask = show_mask; #endif } /* attach the floating selection... */ #if 0 /* BOGUS: we may need to read this, even if we don't support it! */ if (add_floating_sel) { GimpLayer *floating_sel; floating_sel = info->floating_sel; floating_sel_attach (floating_sel, GIMP_DRAWABLE (layer)); } #endif return MagickTrue; }
static Image *ReadWBMPImage(const ImageInfo *image_info, ExceptionInfo *exception) { Image *image; int byte; MagickBooleanType status; register ssize_t x; register Quantum *q; ssize_t y; unsigned char bit; unsigned short header; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info,exception); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } if (ReadBlob(image,2,(unsigned char *) &header) == 0) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if (header != 0) ThrowReaderException(CoderError,"OnlyLevelZerofilesSupported"); /* Initialize image structure. */ if (WBMPReadInteger(image,&image->columns) == MagickFalse) ThrowReaderException(CorruptImageError,"CorruptWBMPimage"); if (WBMPReadInteger(image,&image->rows) == MagickFalse) ThrowReaderException(CorruptImageError,"CorruptWBMPimage"); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if (DiscardBlobBytes(image,image->offset) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); if (AcquireImageColormap(image,2,exception) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if (image_info->ping != MagickFalse) { (void) CloseBlob(image); return(GetFirstImageInList(image)); } status=SetImageExtent(image,image->columns,image->rows,exception); if (status == MagickFalse) return(DestroyImageList(image)); /* Convert bi-level image to pixel packets. */ for (y=0; y < (ssize_t) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; bit=0; byte=0; for (x=0; x < (ssize_t) image->columns; x++) { if (bit == 0) { byte=ReadBlobByte(image); if (byte == EOF) ThrowReaderException(CorruptImageError,"CorruptImage"); } SetPixelIndex(image,(byte & (0x01 << (7-bit))) ? 1 : 0,q); bit++; if (bit == 8) bit=0; q+=GetPixelChannels(image); } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } (void) SyncImage(image,exception); if (EOFBlob(image) != MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d Y C b C r I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadYCBCRImage() reads an image of raw YCbCr or YCbCrA samples and returns % it. It allocates the memory necessary for the new Image structure and % returns a pointer to the new image. % % The format of the ReadYCBCRImage method is: % % Image *ReadYCBCRImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadYCBCRImage(const ImageInfo *image_info, ExceptionInfo *exception) { Image *canvas_image, *image; MagickBooleanType status; MagickOffsetType scene; QuantumInfo *quantum_info; QuantumType quantum_type; register const PixelPacket *p; register ssize_t i, x; register PixelPacket *q; size_t length; ssize_t count, y; unsigned char *pixels; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); SetImageColorspace(image,YCbCrColorspace); if (image_info->interlace != PartitionInterlace) { status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } if (DiscardBlobBytes(image,image->offset) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); } /* Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]). */ canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse, exception); (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod); quantum_info=AcquireQuantumInfo(image_info,canvas_image); if (quantum_info == (QuantumInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); pixels=GetQuantumPixels(quantum_info); quantum_type=RGBQuantum; if (LocaleCompare(image_info->magick,"YCbCrA") == 0) { quantum_type=RGBAQuantum; image->matte=MagickTrue; } if (image_info->number_scenes != 0) while (image->scene < image_info->scene) { /* Skip to next image. */ image->scene++; length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); for (y=0; y < (ssize_t) image->rows; y++) { count=ReadBlob(image,length,pixels); if (count != (ssize_t) length) break; } } count=0; length=0; scene=0; do { /* Read pixels to virtual canvas image then push to image. */ if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; SetImageColorspace(image,YCbCrColorspace); switch (image_info->interlace) { case NoInterlace: default: { /* No interlacing: YCbCrYCbCrYCbCrYCbCrYCbCrYCbCr... */ if (scene == 0) { length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); count=ReadBlob(image,length,pixels); } for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,quantum_type,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=QueueAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelRed(q,GetPixelRed(p)); SetPixelGreen(q,GetPixelGreen(p)); SetPixelBlue(q,GetPixelBlue(p)); if (image->matte != MagickFalse) SetPixelOpacity(q,GetPixelOpacity(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } count=ReadBlob(image,length,pixels); } break; } case LineInterlace: { static QuantumType quantum_types[4] = { RedQuantum, GreenQuantum, BlueQuantum, OpacityQuantum }; /* Line interlacing: YYY...CbCbCb...CrCrCr...YYY...CbCbCb...CrCrCr... */ if (scene == 0) { length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum); count=ReadBlob(image,length,pixels); } for (y=0; y < (ssize_t) image->extract_info.height; y++) { for (i=0; i < (image->matte != MagickFalse ? 4 : 3); i++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } quantum_type=quantum_types[i]; q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,quantum_type,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x, 0,canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { switch (quantum_type) { case RedQuantum: { SetPixelRed(q,GetPixelRed(p)); break; } case GreenQuantum: { SetPixelGreen(q,GetPixelGreen(p)); break; } case BlueQuantum: { SetPixelBlue(q,GetPixelBlue(p)); break; } case OpacityQuantum: { SetPixelOpacity(q,GetPixelOpacity(p)); break; } default: break; } p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } break; } case PlaneInterlace: { /* Plane interlacing: YYYYYY...CbCbCbCbCbCb...CrCrCrCrCrCr... */ if (scene == 0) { length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum); count=ReadBlob(image,length,pixels); } for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,RedQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelRed(q,GetPixelRed(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,1,5); if (status == MagickFalse) break; } for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,GreenQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelGreen(q,GetPixelGreen(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,2,5); if (status == MagickFalse) break; } for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,BlueQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelBlue(q,GetPixelBlue(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,3,5); if (status == MagickFalse) break; } if (image->matte != MagickFalse) { for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,AlphaQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image, canvas_image->extract_info.x,0,canvas_image->columns,1, exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelOpacity(q,GetPixelOpacity(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,4,5); if (status == MagickFalse) break; } } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,5,5); if (status == MagickFalse) break; } break; } case PartitionInterlace: { /* Partition interlacing: YYYYYY..., CbCbCbCbCbCb..., CrCrCrCrCrCr... */ AppendImageFormat("Y",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { canvas_image=DestroyImageList(canvas_image); image=DestroyImageList(image); return((Image *) NULL); } if (DiscardBlobBytes(image,image->offset) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum); for (i=0; i < (ssize_t) scene; i++) for (y=0; y < (ssize_t) image->extract_info.height; y++) if (ReadBlob(image,length,pixels) != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } count=ReadBlob(image,length,pixels); for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,RedQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelRed(q,GetPixelRed(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,1,5); if (status == MagickFalse) break; } (void) CloseBlob(image); AppendImageFormat("Cb",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { canvas_image=DestroyImageList(canvas_image); image=DestroyImageList(image); return((Image *) NULL); } length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum); for (i=0; i < (ssize_t) scene; i++) for (y=0; y < (ssize_t) image->extract_info.height; y++) if (ReadBlob(image,length,pixels) != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } count=ReadBlob(image,length,pixels); for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,GreenQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelGreen(q,GetPixelGreen(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,2,5); if (status == MagickFalse) break; } (void) CloseBlob(image); AppendImageFormat("Cr",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { canvas_image=DestroyImageList(canvas_image); image=DestroyImageList(image); return((Image *) NULL); } length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum); for (i=0; i < (ssize_t) scene; i++) for (y=0; y < (ssize_t) image->extract_info.height; y++) if (ReadBlob(image,length,pixels) != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } count=ReadBlob(image,length,pixels); for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,BlueQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, canvas_image->columns,1,exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelBlue(q,GetPixelBlue(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,3,5); if (status == MagickFalse) break; } if (image->matte != MagickFalse) { (void) CloseBlob(image); AppendImageFormat("A",image->filename); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { canvas_image=DestroyImageList(canvas_image); image=DestroyImageList(image); return((Image *) NULL); } length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum); for (i=0; i < (ssize_t) scene; i++) for (y=0; y < (ssize_t) image->extract_info.height; y++) if (ReadBlob(image,length,pixels) != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } count=ReadBlob(image,length,pixels); for (y=0; y < (ssize_t) image->extract_info.height; y++) { if (count != (ssize_t) length) { ThrowFileException(exception,CorruptImageError, "UnexpectedEndOfFile",image->filename); break; } q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, exception); if (q == (PixelPacket *) NULL) break; length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, quantum_info,BlueQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image, canvas_image->extract_info.x,0,canvas_image->columns,1, exception); q=GetAuthenticPixels(image,0,y-image->extract_info.y, image->columns,1,exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelOpacity(q,GetPixelOpacity(p)); p++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } count=ReadBlob(image,length,pixels); } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,4,5); if (status == MagickFalse) break; } } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,5,5); if (status == MagickFalse) break; } break; } } SetQuantumImageType(image,quantum_type); /* Proceed to next image. */ if (image_info->number_scenes != 0) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; if (count == (ssize_t) length) { /* Allocate next image structure. */ AcquireNextImage(image_info,image); if (GetNextImageInList(image) == (Image *) NULL) { image=DestroyImageList(image); return((Image *) NULL); } image=SyncNextImageInList(image); status=SetImageProgress(image,LoadImagesTag,TellBlob(image), GetBlobSize(image)); if (status == MagickFalse) break; } scene++; } while (count == (ssize_t) length); quantum_info=DestroyQuantumInfo(quantum_info); InheritException(&image->exception,&canvas_image->exception); canvas_image=DestroyImage(canvas_image); (void) CloseBlob(image); return(GetFirstImageInList(image)); }