static MagickBooleanType load_hierarchy(Image *image,XCFDocInfo *inDocInfo, XCFLayerInfo *inLayer, ExceptionInfo *exception) { MagickOffsetType saved_pos, offset, junk; size_t width, height, bytes_per_pixel; width=ReadBlobMSBLong(image); (void) width; height=ReadBlobMSBLong(image); (void) height; bytes_per_pixel=inDocInfo->bytes_per_pixel=ReadBlobMSBLong(image); (void) bytes_per_pixel; /* load in the levels...we make sure that the number of levels * calculated when the TileManager was created is the same * as the number of levels found in the file. */ offset=(MagickOffsetType) ReadBlobMSBLong(image); /* top level */ /* discard offsets for layers below first, if any. */ do { junk=(MagickOffsetType) ReadBlobMSBLong(image); } while (junk != 0); /* save the current position as it is where the * next level offset is stored. */ saved_pos=TellBlob(image); /* seek to the level offset */ offset=SeekBlob(image, offset, SEEK_SET); /* read in the level */ if (load_level (image, inDocInfo, inLayer, exception) == 0) return(MagickFalse); /* restore the saved position so we'll be ready to * read the next offset. */ offset=SeekBlob(image, saved_pos, SEEK_SET); return(MagickTrue); }
static char *ReadBlobStringWithLongSize(Image *image,char *string,size_t max) { int c; MagickOffsetType offset; register ssize_t i; size_t length; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); assert(max != 0); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); length=ReadBlobMSBLong(image); for (i=0; i < (ssize_t) MagickMin(length,max-1); i++) { c=ReadBlobByte(image); if (c == EOF) return((char *) NULL); string[i]=(char) c; } string[i]='\0'; offset=SeekBlob(image,(MagickOffsetType) (length-i),SEEK_CUR); if (offset < 0) (void) ThrowMagickException(&image->exception,GetMagickModule(), CorruptImageError,"ImproperImageHeader","`%s'",image->filename); return(string); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d A V S I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadAVSImage() reads an AVS X 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 ReadAVSImage method is: % % Image *ReadAVSImage(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 *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; MagickBooleanType status; register PixelPacket *q; register ssize_t x; register unsigned char *p; size_t height, length, width; 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); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Read AVS X image. */ width=ReadBlobMSBLong(image); height=ReadBlobMSBLong(image); if (EOFBlob(image) != MagickFalse) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if ((width == 0UL) || (height == 0UL)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); do { /* Convert AVS raster image to pixel packets. */ image->columns=width; image->rows=height; image->depth=8; if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; pixels=(unsigned char *) AcquireQuantumMemory(image->columns, 4*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); length=(size_t) 4*image->columns; for (y=0; y < (ssize_t) image->rows; y++) { count=ReadBlob(image,length,pixels); if ((size_t) count != length) ThrowReaderException(CorruptImageError,"UnableToReadImageData"); p=pixels; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelAlpha(q,ScaleCharToQuantum(*p++)); SetPixelRed(q,ScaleCharToQuantum(*p++)); SetPixelGreen(q,ScaleCharToQuantum(*p++)); SetPixelBlue(q,ScaleCharToQuantum(*p++)); if (q->opacity != OpaqueOpacity) image->matte=MagickTrue; 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=(unsigned char *) RelinquishMagickMemory(pixels); 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; width=ReadBlobMSBLong(image); height=ReadBlobMSBLong(image); if ((width != 0UL) && (height != 0UL)) { /* 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 ((width != 0UL) && (height != 0UL)); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d V I F F I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadVIFFImage() reads a Khoros Visualization 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 ReadVIFFImage method is: % % Image *ReadVIFFImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image: Method ReadVIFFImage returns a pointer to the image after % reading. A null image is returned if there is a memory shortage or if % the image cannot be read. % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadVIFFImage(const ImageInfo *image_info, ExceptionInfo *exception) { #define VFF_CM_genericRGB 15 #define VFF_CM_ntscRGB 1 #define VFF_CM_NONE 0 #define VFF_DEP_DECORDER 0x4 #define VFF_DEP_NSORDER 0x8 #define VFF_DES_RAW 0 #define VFF_LOC_IMPLICIT 1 #define VFF_MAPTYP_NONE 0 #define VFF_MAPTYP_1_BYTE 1 #define VFF_MAPTYP_2_BYTE 2 #define VFF_MAPTYP_4_BYTE 4 #define VFF_MAPTYP_FLOAT 5 #define VFF_MAPTYP_DOUBLE 7 #define VFF_MS_NONE 0 #define VFF_MS_ONEPERBAND 1 #define VFF_MS_SHARED 3 #define VFF_TYP_BIT 0 #define VFF_TYP_1_BYTE 1 #define VFF_TYP_2_BYTE 2 #define VFF_TYP_4_BYTE 4 #define VFF_TYP_FLOAT 5 #define VFF_TYP_DOUBLE 9 typedef struct _ViffInfo { unsigned char identifier, file_type, release, version, machine_dependency, reserve[3]; char comment[512]; unsigned int rows, columns, subrows; int x_offset, y_offset; float x_bits_per_pixel, y_bits_per_pixel; unsigned int location_type, location_dimension, number_of_images, number_data_bands, data_storage_type, data_encode_scheme, map_scheme, map_storage_type, map_rows, map_columns, map_subrows, map_enable, maps_per_cycle, color_space_model; } ViffInfo; double min_value, scale_factor, value; Image *image; int bit; MagickBooleanType status; MagickSizeType number_pixels; register ssize_t x; register Quantum *q; register ssize_t i; register unsigned char *p; size_t bytes_per_pixel, lsb_first, max_packets, quantum; ssize_t count, y; unsigned char buffer[7], *viff_pixels; ViffInfo viff_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,exception); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Read VIFF header (1024 bytes). */ count=ReadBlob(image,1,&viff_info.identifier); do { /* Verify VIFF identifier. */ if ((count == 0) || ((unsigned char) viff_info.identifier != 0xab)) ThrowReaderException(CorruptImageError,"NotAVIFFImage"); /* Initialize VIFF image. */ count=ReadBlob(image,7,buffer); viff_info.file_type=buffer[0]; viff_info.release=buffer[1]; viff_info.version=buffer[2]; viff_info.machine_dependency=buffer[3]; count=ReadBlob(image,512,(unsigned char *) viff_info.comment); viff_info.comment[511]='\0'; if (strlen(viff_info.comment) > 4) (void) SetImageProperty(image,"comment",viff_info.comment,exception); if ((viff_info.machine_dependency == VFF_DEP_DECORDER) || (viff_info.machine_dependency == VFF_DEP_NSORDER)) { viff_info.rows=ReadBlobLSBLong(image); viff_info.columns=ReadBlobLSBLong(image); viff_info.subrows=ReadBlobLSBLong(image); viff_info.x_offset=(int) ReadBlobLSBLong(image); viff_info.y_offset=(int) ReadBlobLSBLong(image); viff_info.x_bits_per_pixel=(float) ReadBlobLSBLong(image); viff_info.y_bits_per_pixel=(float) ReadBlobLSBLong(image); viff_info.location_type=ReadBlobLSBLong(image); viff_info.location_dimension=ReadBlobLSBLong(image); viff_info.number_of_images=ReadBlobLSBLong(image); viff_info.number_data_bands=ReadBlobLSBLong(image); viff_info.data_storage_type=ReadBlobLSBLong(image); viff_info.data_encode_scheme=ReadBlobLSBLong(image); viff_info.map_scheme=ReadBlobLSBLong(image); viff_info.map_storage_type=ReadBlobLSBLong(image); viff_info.map_rows=ReadBlobLSBLong(image); viff_info.map_columns=ReadBlobLSBLong(image); viff_info.map_subrows=ReadBlobLSBLong(image); viff_info.map_enable=ReadBlobLSBLong(image); viff_info.maps_per_cycle=ReadBlobLSBLong(image); viff_info.color_space_model=ReadBlobLSBLong(image); } else { viff_info.rows=ReadBlobMSBLong(image); viff_info.columns=ReadBlobMSBLong(image); viff_info.subrows=ReadBlobMSBLong(image); viff_info.x_offset=(int) ReadBlobMSBLong(image); viff_info.y_offset=(int) ReadBlobMSBLong(image); viff_info.x_bits_per_pixel=(float) ReadBlobMSBLong(image); viff_info.y_bits_per_pixel=(float) ReadBlobMSBLong(image); viff_info.location_type=ReadBlobMSBLong(image); viff_info.location_dimension=ReadBlobMSBLong(image); viff_info.number_of_images=ReadBlobMSBLong(image); viff_info.number_data_bands=ReadBlobMSBLong(image); viff_info.data_storage_type=ReadBlobMSBLong(image); viff_info.data_encode_scheme=ReadBlobMSBLong(image); viff_info.map_scheme=ReadBlobMSBLong(image); viff_info.map_storage_type=ReadBlobMSBLong(image); viff_info.map_rows=ReadBlobMSBLong(image); viff_info.map_columns=ReadBlobMSBLong(image); viff_info.map_subrows=ReadBlobMSBLong(image); viff_info.map_enable=ReadBlobMSBLong(image); viff_info.maps_per_cycle=ReadBlobMSBLong(image); viff_info.color_space_model=ReadBlobMSBLong(image); } for (i=0; i < 420; i++) (void) ReadBlobByte(image); image->columns=viff_info.rows; image->rows=viff_info.columns; image->depth=viff_info.x_bits_per_pixel <= 8 ? 8UL : MAGICKCORE_QUANTUM_DEPTH; /* Verify that we can read this VIFF image. */ number_pixels=(MagickSizeType) viff_info.columns*viff_info.rows; if (number_pixels != (size_t) number_pixels) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if (number_pixels == 0) ThrowReaderException(CoderError,"ImageColumnOrRowSizeIsNotSupported"); if ((viff_info.number_data_bands < 1) || (viff_info.number_data_bands > 4)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if ((viff_info.data_storage_type != VFF_TYP_BIT) && (viff_info.data_storage_type != VFF_TYP_1_BYTE) && (viff_info.data_storage_type != VFF_TYP_2_BYTE) && (viff_info.data_storage_type != VFF_TYP_4_BYTE) && (viff_info.data_storage_type != VFF_TYP_FLOAT) && (viff_info.data_storage_type != VFF_TYP_DOUBLE)) ThrowReaderException(CoderError,"DataStorageTypeIsNotSupported"); if (viff_info.data_encode_scheme != VFF_DES_RAW) ThrowReaderException(CoderError,"DataEncodingSchemeIsNotSupported"); if ((viff_info.map_storage_type != VFF_MAPTYP_NONE) && (viff_info.map_storage_type != VFF_MAPTYP_1_BYTE) && (viff_info.map_storage_type != VFF_MAPTYP_2_BYTE) && (viff_info.map_storage_type != VFF_MAPTYP_4_BYTE) && (viff_info.map_storage_type != VFF_MAPTYP_FLOAT) && (viff_info.map_storage_type != VFF_MAPTYP_DOUBLE)) ThrowReaderException(CoderError,"MapStorageTypeIsNotSupported"); if ((viff_info.color_space_model != VFF_CM_NONE) && (viff_info.color_space_model != VFF_CM_ntscRGB) && (viff_info.color_space_model != VFF_CM_genericRGB)) ThrowReaderException(CoderError,"ColorspaceModelIsNotSupported"); if (viff_info.location_type != VFF_LOC_IMPLICIT) ThrowReaderException(CoderError,"LocationTypeIsNotSupported"); if (viff_info.number_of_images != 1) ThrowReaderException(CoderError,"NumberOfImagesIsNotSupported"); if (viff_info.map_rows == 0) viff_info.map_scheme=VFF_MS_NONE; switch ((int) viff_info.map_scheme) { case VFF_MS_NONE: { if (viff_info.number_data_bands < 3) { /* Create linear color ramp. */ image->colors=image->depth <= 8 ? 256UL : 65536UL; if (viff_info.data_storage_type == VFF_TYP_BIT) image->colors=2; if (AcquireImageColormap(image,image->colors,exception) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } break; } case VFF_MS_ONEPERBAND: case VFF_MS_SHARED: { unsigned char *viff_colormap; /* Allocate VIFF colormap. */ switch ((int) viff_info.map_storage_type) { case VFF_MAPTYP_1_BYTE: bytes_per_pixel=1; break; case VFF_MAPTYP_2_BYTE: bytes_per_pixel=2; break; case VFF_MAPTYP_4_BYTE: bytes_per_pixel=4; break; case VFF_MAPTYP_FLOAT: bytes_per_pixel=4; break; case VFF_MAPTYP_DOUBLE: bytes_per_pixel=8; break; default: bytes_per_pixel=1; break; } image->colors=viff_info.map_columns; if (AcquireImageColormap(image,image->colors,exception) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); viff_colormap=(unsigned char *) AcquireQuantumMemory(image->colors, viff_info.map_rows*bytes_per_pixel*sizeof(*viff_colormap)); if (viff_colormap == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); /* Read VIFF raster colormap. */ count=ReadBlob(image,bytes_per_pixel*image->colors*viff_info.map_rows, viff_colormap); lsb_first=1; if (*(char *) &lsb_first && ((viff_info.machine_dependency != VFF_DEP_DECORDER) && (viff_info.machine_dependency != VFF_DEP_NSORDER))) switch ((int) viff_info.map_storage_type) { case VFF_MAPTYP_2_BYTE: { MSBOrderShort(viff_colormap,(bytes_per_pixel*image->colors* viff_info.map_rows)); break; } case VFF_MAPTYP_4_BYTE: case VFF_MAPTYP_FLOAT: { MSBOrderLong(viff_colormap,(bytes_per_pixel*image->colors* viff_info.map_rows)); break; } default: break; } for (i=0; i < (ssize_t) (viff_info.map_rows*image->colors); i++) { switch ((int) viff_info.map_storage_type) { case VFF_MAPTYP_2_BYTE: value=1.0*((short *) viff_colormap)[i]; break; case VFF_MAPTYP_4_BYTE: value=1.0*((int *) viff_colormap)[i]; break; case VFF_MAPTYP_FLOAT: value=((float *) viff_colormap)[i]; break; case VFF_MAPTYP_DOUBLE: value=((double *) viff_colormap)[i]; break; default: value=1.0*viff_colormap[i]; break; } if (i < (ssize_t) image->colors) { image->colormap[i].red=ScaleCharToQuantum((unsigned char) value); image->colormap[i].green= ScaleCharToQuantum((unsigned char) value); image->colormap[i].blue=ScaleCharToQuantum((unsigned char) value); } else if (i < (ssize_t) (2*image->colors)) image->colormap[i % image->colors].green= ScaleCharToQuantum((unsigned char) value); else if (i < (ssize_t) (3*image->colors)) image->colormap[i % image->colors].blue= ScaleCharToQuantum((unsigned char) value); } viff_colormap=(unsigned char *) RelinquishMagickMemory(viff_colormap); break; } default: ThrowReaderException(CoderError,"ColormapTypeNotSupported"); } /* Initialize image structure. */ image->alpha_trait=viff_info.number_data_bands == 4 ? BlendPixelTrait : UndefinedPixelTrait; image->storage_class=(viff_info.number_data_bands < 3 ? PseudoClass : DirectClass); image->columns=viff_info.rows; image->rows=viff_info.columns; if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; /* Allocate VIFF pixels. */ switch ((int) viff_info.data_storage_type) { case VFF_TYP_2_BYTE: bytes_per_pixel=2; break; case VFF_TYP_4_BYTE: bytes_per_pixel=4; break; case VFF_TYP_FLOAT: bytes_per_pixel=4; break; case VFF_TYP_DOUBLE: bytes_per_pixel=8; break; default: bytes_per_pixel=1; break; } if (viff_info.data_storage_type == VFF_TYP_BIT) max_packets=((image->columns+7UL) >> 3UL)*image->rows; else max_packets=(size_t) (number_pixels*viff_info.number_data_bands); viff_pixels=(unsigned char *) AcquireQuantumMemory(max_packets, bytes_per_pixel*sizeof(*viff_pixels)); if (viff_pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,bytes_per_pixel*max_packets,viff_pixels); lsb_first=1; if (*(char *) &lsb_first && ((viff_info.machine_dependency != VFF_DEP_DECORDER) && (viff_info.machine_dependency != VFF_DEP_NSORDER))) switch ((int) viff_info.data_storage_type) { case VFF_TYP_2_BYTE: { MSBOrderShort(viff_pixels,bytes_per_pixel*max_packets); break; } case VFF_TYP_4_BYTE: case VFF_TYP_FLOAT: { MSBOrderLong(viff_pixels,bytes_per_pixel*max_packets); break; } default: break; } min_value=0.0; scale_factor=1.0; if ((viff_info.data_storage_type != VFF_TYP_1_BYTE) && (viff_info.map_scheme == VFF_MS_NONE)) { double max_value; /* Determine scale factor. */ switch ((int) viff_info.data_storage_type) { case VFF_TYP_2_BYTE: value=1.0*((short *) viff_pixels)[0]; break; case VFF_TYP_4_BYTE: value=1.0*((int *) viff_pixels)[0]; break; case VFF_TYP_FLOAT: value=((float *) viff_pixels)[0]; break; case VFF_TYP_DOUBLE: value=((double *) viff_pixels)[0]; break; default: value=1.0*viff_pixels[0]; break; } max_value=value; min_value=value; for (i=0; i < (ssize_t) max_packets; i++) { switch ((int) viff_info.data_storage_type) { case VFF_TYP_2_BYTE: value=1.0*((short *) viff_pixels)[i]; break; case VFF_TYP_4_BYTE: value=1.0*((int *) viff_pixels)[i]; break; case VFF_TYP_FLOAT: value=((float *) viff_pixels)[i]; break; case VFF_TYP_DOUBLE: value=((double *) viff_pixels)[i]; break; default: value=1.0*viff_pixels[i]; break; } if (value > max_value) max_value=value; else if (value < min_value) min_value=value; } if ((min_value == 0) && (max_value == 0)) scale_factor=0; else if (min_value == max_value) { scale_factor=(double) QuantumRange/min_value; min_value=0; } else scale_factor=(double) QuantumRange/(max_value-min_value); } /* Convert pixels to Quantum size. */ p=(unsigned char *) viff_pixels; for (i=0; i < (ssize_t) max_packets; i++) { switch ((int) viff_info.data_storage_type) { case VFF_TYP_2_BYTE: value=1.0*((short *) viff_pixels)[i]; break; case VFF_TYP_4_BYTE: value=1.0*((int *) viff_pixels)[i]; break; case VFF_TYP_FLOAT: value=((float *) viff_pixels)[i]; break; case VFF_TYP_DOUBLE: value=((double *) viff_pixels)[i]; break; default: value=1.0*viff_pixels[i]; break; } if (viff_info.map_scheme == VFF_MS_NONE) { value=(value-min_value)*scale_factor; if (value > QuantumRange) value=QuantumRange; else if (value < 0) value=0; } *p=(unsigned char) value; p++; } /* Convert VIFF raster image to pixel packets. */ p=(unsigned char *) viff_pixels; if (viff_info.data_storage_type == VFF_TYP_BIT) { /* Convert bitmap scanline. */ (void) SetImageType(image,BilevelType,exception); (void) SetImageType(image,PaletteType,exception); for (y=0; y < (ssize_t) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (x=0; x < (ssize_t) (image->columns-7); x+=8) { for (bit=0; bit < 8; bit++) { if (GetPixelLuma(image,q) < (QuantumRange/2.0)) { quantum=(size_t) GetPixelIndex(image,q); quantum|=0x01; SetPixelIndex(image,quantum,q); } q+=GetPixelChannels(image); } p++; } if ((image->columns % 8) != 0) { for (bit=0; bit < (ssize_t) (image->columns % 8); bit++) if (GetPixelLuma(image,q) < (QuantumRange/2.0)) { quantum=(size_t) GetPixelIndex(image,q); quantum|=0x01; SetPixelIndex(image,quantum,q); q+=GetPixelChannels(image); } p++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } } else if (image->storage_class == PseudoClass) for (y=0; y < (ssize_t) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelIndex(image,*p++,q); q+=GetPixelChannels(image); } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } else { /* Convert DirectColor scanline. */ number_pixels=(MagickSizeType) image->columns*image->rows; for (y=0; y < (ssize_t) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelRed(image,ScaleCharToQuantum(*p),q); SetPixelGreen(image,ScaleCharToQuantum(*(p+number_pixels)),q); SetPixelBlue(image,ScaleCharToQuantum(*(p+2*number_pixels)),q); if (image->colors != 0) { SetPixelRed(image,image->colormap[(ssize_t) GetPixelRed(image,q)].red,q); SetPixelGreen(image,image->colormap[(ssize_t) GetPixelGreen(image,q)].green,q); SetPixelBlue(image,image->colormap[(ssize_t) GetPixelBlue(image,q)].blue,q); } SetPixelAlpha(image,image->alpha_trait == BlendPixelTrait ? ScaleCharToQuantum(*(p+number_pixels*3)) : OpaqueAlpha,q); p++; q+=GetPixelChannels(image); } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } } viff_pixels=(unsigned char *) RelinquishMagickMemory(viff_pixels); if (image->storage_class == PseudoClass) (void) SyncImage(image,exception); 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; count=ReadBlob(image,1,&viff_info.identifier); if ((count != 0) && (viff_info.identifier == 0xab)) { /* Allocate next image structure. */ AcquireNextImage(image_info,image,exception); 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) && (viff_info.identifier == 0xab));
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d P I X I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadPIXImage() reads a Alias/Wavefront RLE 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 ReadPIXImage method is: % % Image *ReadPIXImage(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 *ReadPIXImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; IndexPacket index; MagickBooleanType status; Quantum blue, green, red; register IndexPacket *indexes; register ssize_t x; register PixelPacket *q; size_t bits_per_pixel, height, length, width; ssize_t 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); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Read PIX image. */ width=ReadBlobMSBShort(image); height=ReadBlobMSBShort(image); (void) ReadBlobMSBShort(image); /* x-offset */ (void) ReadBlobMSBShort(image); /* y-offset */ bits_per_pixel=ReadBlobMSBShort(image); if ((width == 0UL) || (height == 0UL) || ((bits_per_pixel != 8) && (bits_per_pixel != 24))) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); do { /* Initialize image structure. */ image->columns=width; image->rows=height; if (bits_per_pixel == 8) if (AcquireImageColormap(image,256) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; /* Convert PIX raster image to pixel packets. */ red=(Quantum) 0; green=(Quantum) 0; blue=(Quantum) 0; index=(IndexPacket) 0; length=0; for (y=0; y < (ssize_t) image->rows; y++) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; indexes=GetAuthenticIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { if (length == 0) { length=(size_t) ReadBlobByte(image); if (bits_per_pixel == 8) index=ScaleCharToQuantum((unsigned char) ReadBlobByte(image)); else { blue=ScaleCharToQuantum((unsigned char) ReadBlobByte(image)); green=ScaleCharToQuantum((unsigned char) ReadBlobByte(image)); red=ScaleCharToQuantum((unsigned char) ReadBlobByte(image)); } } if (image->storage_class == PseudoClass) SetPixelIndex(indexes+x,index); SetPixelBlue(q,blue); SetPixelGreen(q,green); SetPixelRed(q,red); length--; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } if (image->storage_class == PseudoClass) (void) SyncImage(image); 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; width=ReadBlobMSBLong(image); height=ReadBlobMSBLong(image); (void) ReadBlobMSBShort(image); (void) ReadBlobMSBShort(image); bits_per_pixel=ReadBlobMSBShort(image); status=(width != 0UL) && (height == 0UL) && ((bits_per_pixel == 8) || (bits_per_pixel == 24)) ? MagickTrue : MagickFalse; if (status == MagickTrue) { /* 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 (status == MagickTrue); (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); for (i=0; i < (ssize_t) (3L*num_colours); i++ ) (void) ReadBlobByte(image); /* 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 */ for (i=0; i < (ssize_t) prop_size; i++ ) if (ReadBlobByte(image) == EOF) ThrowFileException(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 */ for (i=0; i < (ssize_t) prop_size; i++ ) if (ReadBlobByte(image) == EOF) ThrowFileException(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 */ for (i=0; i< (ssize_t) prop_size; i++ ) if (ReadBlobByte(image) == EOF) ThrowFileException(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 = (ssize_t) 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 ) { ssize_t i; 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 = (ssize_t) ReadBlobMSBLong(image); outLayer->offset_y = (ssize_t) ReadBlobMSBLong(image); break; case PROP_MODE: outLayer->mode = ReadBlobMSBLong(image); break; case PROP_TATTOO: outLayer->preserve_trans = ReadBlobMSBLong(image); break; case PROP_PARASITES: { for (i=0; i < (ssize_t) prop_size; i++ ) (void) ReadBlobByte(image); /* 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 MagickBooleanType load_level(Image *image,XCFDocInfo *inDocInfo, XCFLayerInfo *inLayerInfo) { ExceptionInfo *exception; int destLeft = 0, destTop = 0; Image* tile_image; MagickBooleanType status; MagickOffsetType saved_pos, offset, offset2; register ssize_t i; size_t width, height, ntiles, ntile_rows, ntile_cols, tile_image_width, tile_image_height; /* start reading the data */ exception=inDocInfo->exception; width=ReadBlobMSBLong(image); height=ReadBlobMSBLong(image); /* read in the first tile offset. * if it is '0', then this tile level is empty * and we can simply return. */ offset=(MagickOffsetType) ReadBlobMSBLong(image); if (offset == 0) return(MagickTrue); /* Initialise the reference for the in-memory tile-compression */ ntile_rows=(height+TILE_HEIGHT-1)/TILE_HEIGHT; ntile_cols=(width+TILE_WIDTH-1)/TILE_WIDTH; ntiles=ntile_rows*ntile_cols; for (i = 0; i < (ssize_t) ntiles; i++) { status=MagickFalse; if (offset == 0) ThrowBinaryException(CorruptImageError,"NotEnoughTiles",image->filename); /* save the current position as it is where the * next tile offset is stored. */ saved_pos=TellBlob(image); /* read in the offset of the next tile so we can calculate the amount of data needed for this tile*/ offset2=(MagickOffsetType)ReadBlobMSBLong(image); /* if the offset is 0 then we need to read in the maximum possible allowing for negative compression */ if (offset2 == 0) offset2=(MagickOffsetType) (offset + TILE_WIDTH * TILE_WIDTH * 4* 1.5); /* seek to the tile offset */ offset=SeekBlob(image, offset, SEEK_SET); /* allocate the image for the tile NOTE: the last tile in a row or column may not be a full tile! */ tile_image_width=(size_t) (destLeft == (int) ntile_cols-1 ? (int) width % TILE_WIDTH : TILE_WIDTH); if (tile_image_width == 0) tile_image_width=TILE_WIDTH; tile_image_height = (size_t) (destTop == (int) ntile_rows-1 ? (int) height % TILE_HEIGHT : TILE_HEIGHT); if (tile_image_height == 0) tile_image_height=TILE_HEIGHT; tile_image=CloneImage(inLayerInfo->image,tile_image_width, tile_image_height,MagickTrue,exception); /* read in the tile */ switch (inDocInfo->compression) { case COMPRESS_NONE: if (load_tile(image,tile_image,inDocInfo,inLayerInfo,(size_t) (offset2-offset)) == 0) status=MagickTrue; break; case COMPRESS_RLE: if (load_tile_rle (image,tile_image,inDocInfo,inLayerInfo, (int) (offset2-offset)) == 0) status=MagickTrue; break; case COMPRESS_ZLIB: ThrowBinaryException(CoderError,"ZipCompressNotSupported", image->filename) case COMPRESS_FRACTAL: ThrowBinaryException(CoderError,"FractalCompressNotSupported", image->filename) } /* composite the tile onto the layer's image, and then destroy it */ (void) CompositeImage(inLayerInfo->image,CopyCompositeOp,tile_image, destLeft * TILE_WIDTH,destTop*TILE_HEIGHT); tile_image=DestroyImage(tile_image); /* adjust tile position */ destLeft++; if (destLeft >= (int) ntile_cols) { destLeft = 0; destTop++; } if (status != MagickFalse) return(MagickFalse); /* restore the saved position so we'll be ready to * read the next offset. */ offset=SeekBlob(image, saved_pos, SEEK_SET); /* read in the offset of the next tile */ offset=(MagickOffsetType) ReadBlobMSBLong(image); } if (offset != 0) ThrowBinaryException(CorruptImageError,"CorruptImage",image->filename) return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d R L A I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadRLAImage() reads a run-length encoded Wavefront RLA image file % and returns it. It allocates the memory necessary for the new Image % structure and returns a pointer to the new image. % % Note: This module was contributed by Lester Vecsey ([email protected]). % % The format of the ReadRLAImage method is: % % Image *ReadRLAImage(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 *ReadRLAImage(const ImageInfo *image_info,ExceptionInfo *exception) { typedef struct _WindowFrame { short left, right, bottom, top; } WindowFrame; typedef struct _RLAInfo { WindowFrame window, active_window; short frame, storage_type, number_channels, number_matte_channels, number_auxiliary_channels, revision; char gamma[16], red_primary[24], green_primary[24], blue_primary[24], white_point[24]; ssize_t job_number; char name[128], description[128], program[64], machine[32], user[32], date[20], aspect[24], aspect_ratio[8], chan[32]; short field; char time[12], filter[32]; short bits_per_channel, matte_type, matte_bits, auxiliary_type, auxiliary_bits; char auxiliary[32], space[36]; ssize_t next; } RLAInfo; Image *image; int channel, length, runlength; MagickBooleanType status; MagickOffsetType offset; register ssize_t i, x; register PixelPacket *q; ssize_t count, *scanlines, y; RLAInfo rla_info; unsigned char byte; /* 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); } rla_info.window.left=(short) ReadBlobMSBShort(image); rla_info.window.right=(short) ReadBlobMSBShort(image); rla_info.window.bottom=(short) ReadBlobMSBShort(image); rla_info.window.top=(short) ReadBlobMSBShort(image); rla_info.active_window.left=(short) ReadBlobMSBShort(image); rla_info.active_window.right=(short) ReadBlobMSBShort(image); rla_info.active_window.bottom=(short) ReadBlobMSBShort(image); rla_info.active_window.top=(short) ReadBlobMSBShort(image); rla_info.frame=(short) ReadBlobMSBShort(image); rla_info.storage_type=(short) ReadBlobMSBShort(image); rla_info.number_channels=(short) ReadBlobMSBShort(image); rla_info.number_matte_channels=(short) ReadBlobMSBShort(image); if (rla_info.number_channels == 0) rla_info.number_channels=3; rla_info.number_channels+=rla_info.number_matte_channels; rla_info.number_auxiliary_channels=(short) ReadBlobMSBShort(image); rla_info.revision=(short) ReadBlobMSBShort(image); count=ReadBlob(image,16,(unsigned char *) rla_info.gamma); count=ReadBlob(image,24,(unsigned char *) rla_info.red_primary); count=ReadBlob(image,24,(unsigned char *) rla_info.green_primary); count=ReadBlob(image,24,(unsigned char *) rla_info.blue_primary); count=ReadBlob(image,24,(unsigned char *) rla_info.white_point); rla_info.job_number=(int) ReadBlobMSBLong(image); count=ReadBlob(image,128,(unsigned char *) rla_info.name); count=ReadBlob(image,128,(unsigned char *) rla_info.description); count=ReadBlob(image,64,(unsigned char *) rla_info.program); count=ReadBlob(image,32,(unsigned char *) rla_info.machine); count=ReadBlob(image,32,(unsigned char *) rla_info.user); count=ReadBlob(image,20,(unsigned char *) rla_info.date); count=ReadBlob(image,24,(unsigned char *) rla_info.aspect); count=ReadBlob(image,8,(unsigned char *) rla_info.aspect_ratio); count=ReadBlob(image,32,(unsigned char *) rla_info.chan); rla_info.field=(short) ReadBlobMSBShort(image); count=ReadBlob(image,12,(unsigned char *) rla_info.time); count=ReadBlob(image,32,(unsigned char *) rla_info.filter); rla_info.bits_per_channel=(short) ReadBlobMSBShort(image); rla_info.matte_type=(short) ReadBlobMSBShort(image); rla_info.matte_bits=(short) ReadBlobMSBShort(image); rla_info.auxiliary_type=(short) ReadBlobMSBShort(image); rla_info.auxiliary_bits=(short) ReadBlobMSBShort(image); count=ReadBlob(image,32,(unsigned char *) rla_info.auxiliary); count=ReadBlob(image,36,(unsigned char *) rla_info.space); if ((size_t) count != 36) ThrowReaderException(CorruptImageError,"UnableToReadImageData"); rla_info.next=(int) ReadBlobMSBLong(image); /* Initialize image structure. */ image->matte=rla_info.number_matte_channels != 0 ? MagickTrue : MagickFalse; image->columns=1UL*rla_info.active_window.right-rla_info.active_window.left+1; image->rows=1UL*rla_info.active_window.top-rla_info.active_window.bottom+1; if (image_info->ping != MagickFalse) { (void) CloseBlob(image); return(GetFirstImageInList(image)); } scanlines=(ssize_t *) AcquireQuantumMemory(image->rows,sizeof(*scanlines)); if (scanlines == (ssize_t *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if (*rla_info.description != '\0') (void) SetImageProperty(image,"comment",rla_info.description); /* Read offsets to each scanline data. */ for (i=0; i < (ssize_t) image->rows; i++) scanlines[i]=(int) ReadBlobMSBLong(image); /* Read image data. */ x=0; for (y=0; y < (ssize_t) image->rows; y++) { offset=SeekBlob(image,scanlines[image->rows-y-1],SEEK_SET); if (offset < 0) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); for (channel=0; channel < (int) rla_info.number_channels; channel++) { length=(int) ReadBlobMSBShort(image); while (length > 0) { byte=(unsigned char) ReadBlobByte(image); runlength=byte; if (byte > 127) runlength=byte-256; length--; if (length == 0) break; if (runlength < 0) { while (runlength < 0) { q=GetAuthenticPixels(image,(ssize_t) (x % image->columns), (ssize_t) (y % image->rows),1,1,exception); if (q == (PixelPacket *) NULL) break; byte=(unsigned char) ReadBlobByte(image); length--; switch (channel) { case 0: { SetPixelRed(q,ScaleCharToQuantum(byte)); break; } case 1: { SetPixelGreen(q,ScaleCharToQuantum(byte)); break; } case 2: { SetPixelBlue(q,ScaleCharToQuantum(byte)); break; } case 3: default: { SetPixelAlpha(q,ScaleCharToQuantum(byte)); break; } } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; x++; runlength++; } continue; } byte=(unsigned char) ReadBlobByte(image); length--; runlength++; do { q=GetAuthenticPixels(image,(ssize_t) (x % image->columns), (ssize_t) (y % image->rows),1,1,exception); if (q == (PixelPacket *) NULL) break; switch (channel) { case 0: { SetPixelRed(q,ScaleCharToQuantum(byte)); break; } case 1: { SetPixelGreen(q,ScaleCharToQuantum(byte)); break; } case 2: { SetPixelBlue(q,ScaleCharToQuantum(byte)); break; } case 3: default: { SetPixelAlpha(q,ScaleCharToQuantum(byte)); break; } } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; x++; runlength--; } while (runlength > 0); } } status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } if (EOFBlob(image) != MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
static Image *ReadSGIImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; MagickBooleanType status; MagickSizeType number_pixels; MemoryInfo *pixel_info; register IndexPacket *indexes; register PixelPacket *q; register ssize_t i, x; register unsigned char *p; SGIInfo iris_info; size_t bytes_per_pixel, quantum; ssize_t count, y, z; 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); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Read SGI raster header. */ iris_info.magic=ReadBlobMSBShort(image); do { /* Verify SGI identifier. */ if (iris_info.magic != 0x01DA) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); iris_info.storage=(unsigned char) ReadBlobByte(image); switch (iris_info.storage) { case 0x00: image->compression=NoCompression; break; case 0x01: image->compression=RLECompression; break; default: ThrowReaderException(CorruptImageError,"ImproperImageHeader"); } iris_info.bytes_per_pixel=(unsigned char) ReadBlobByte(image); if ((iris_info.bytes_per_pixel == 0) || (iris_info.bytes_per_pixel > 2)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); iris_info.dimension=ReadBlobMSBShort(image); iris_info.columns=ReadBlobMSBShort(image); iris_info.rows=ReadBlobMSBShort(image); iris_info.depth=ReadBlobMSBShort(image); if ((iris_info.depth == 0) || (iris_info.depth > 4)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); iris_info.minimum_value=ReadBlobMSBLong(image); iris_info.maximum_value=ReadBlobMSBLong(image); iris_info.sans=ReadBlobMSBLong(image); (void) ReadBlob(image,sizeof(iris_info.name),(unsigned char *) iris_info.name); iris_info.name[sizeof(iris_info.name)-1]='\0'; if (*iris_info.name != '\0') (void) SetImageProperty(image,"label",iris_info.name); iris_info.pixel_format=ReadBlobMSBLong(image); if (iris_info.pixel_format != 0) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); count=ReadBlob(image,sizeof(iris_info.filler),iris_info.filler); (void) count; image->columns=iris_info.columns; image->rows=iris_info.rows; image->depth=(size_t) MagickMin(iris_info.depth,MAGICKCORE_QUANTUM_DEPTH); if (iris_info.pixel_format == 0) image->depth=(size_t) MagickMin((size_t) 8* iris_info.bytes_per_pixel,MAGICKCORE_QUANTUM_DEPTH); if (iris_info.depth < 3) { image->storage_class=PseudoClass; image->colors=iris_info.bytes_per_pixel > 1 ? 65535 : 256; } 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)); } /* Allocate SGI pixels. */ bytes_per_pixel=(size_t) iris_info.bytes_per_pixel; number_pixels=(MagickSizeType) iris_info.columns*iris_info.rows; if ((4*bytes_per_pixel*number_pixels) != ((MagickSizeType) (size_t) (4*bytes_per_pixel*number_pixels))) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); pixel_info=AcquireVirtualMemory(iris_info.columns,iris_info.rows*4* bytes_per_pixel*sizeof(*pixels)); if (pixel_info == (MemoryInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info); if ((int) iris_info.storage != 0x01) { unsigned char *scanline; /* Read standard image format. */ scanline=(unsigned char *) AcquireQuantumMemory(iris_info.columns, bytes_per_pixel*sizeof(*scanline)); if (scanline == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); for (z=0; z < (ssize_t) iris_info.depth; z++) { p=pixels+bytes_per_pixel*z; for (y=0; y < (ssize_t) iris_info.rows; y++) { count=ReadBlob(image,bytes_per_pixel*iris_info.columns,scanline); if (EOFBlob(image) != MagickFalse) break; if (bytes_per_pixel == 2) for (x=0; x < (ssize_t) iris_info.columns; x++) { *p=scanline[2*x]; *(p+1)=scanline[2*x+1]; p+=8; } else for (x=0; x < (ssize_t) iris_info.columns; x++) { *p=scanline[x]; p+=4; } } } scanline=(unsigned char *) RelinquishMagickMemory(scanline); } else { MemoryInfo *packet_info; size_t *runlength; ssize_t offset, *offsets; unsigned char *packets; unsigned int data_order; /* Read runlength-encoded image format. */ offsets=(ssize_t *) AcquireQuantumMemory((size_t) iris_info.rows, iris_info.depth*sizeof(*offsets)); runlength=(size_t *) AcquireQuantumMemory(iris_info.rows, iris_info.depth*sizeof(*runlength)); packet_info=AcquireVirtualMemory((size_t) iris_info.columns+10UL,4UL* sizeof(*packets)); if ((offsets == (ssize_t *) NULL) || (runlength == (size_t *) NULL) || (packet_info == (MemoryInfo *) NULL)) { if (offsets == (ssize_t *) NULL) offsets=(ssize_t *) RelinquishMagickMemory(offsets); if (runlength == (size_t *) NULL) runlength=(size_t *) RelinquishMagickMemory(runlength); if (packet_info == (MemoryInfo *) NULL) packet_info=RelinquishVirtualMemory(packet_info); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } packets=(unsigned char *) GetVirtualMemoryBlob(packet_info); for (i=0; i < (ssize_t) (iris_info.rows*iris_info.depth); i++) offsets[i]=(int) ReadBlobMSBLong(image); for (i=0; i < (ssize_t) (iris_info.rows*iris_info.depth); i++) { runlength[i]=ReadBlobMSBLong(image); if (runlength[i] > (4*(size_t) iris_info.columns+10)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); } /* Check data order. */ offset=0; data_order=0; for (y=0; ((y < (ssize_t) iris_info.rows) && (data_order == 0)); y++) for (z=0; ((z < (ssize_t) iris_info.depth) && (data_order == 0)); z++) { if (offsets[y+z*iris_info.rows] < offset) data_order=1; offset=offsets[y+z*iris_info.rows]; } offset=(ssize_t) TellBlob(image); if (data_order == 1) { for (z=0; z < (ssize_t) iris_info.depth; z++) { p=pixels; for (y=0; y < (ssize_t) iris_info.rows; y++) { if (offset != offsets[y+z*iris_info.rows]) { offset=offsets[y+z*iris_info.rows]; offset=(ssize_t) SeekBlob(image,(ssize_t) offset,SEEK_SET); } count=ReadBlob(image,(size_t) runlength[y+z*iris_info.rows], packets); if (EOFBlob(image) != MagickFalse) break; offset+=(ssize_t) runlength[y+z*iris_info.rows]; status=SGIDecode(bytes_per_pixel,(ssize_t) (runlength[y+z*iris_info.rows]/bytes_per_pixel),packets, 1L*iris_info.columns,p+bytes_per_pixel*z); if (status == MagickFalse) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); p+=(iris_info.columns*4*bytes_per_pixel); } } } else { MagickOffsetType position; position=TellBlob(image); p=pixels; for (y=0; y < (ssize_t) iris_info.rows; y++) { for (z=0; z < (ssize_t) iris_info.depth; z++) { if (offset != offsets[y+z*iris_info.rows]) { offset=offsets[y+z*iris_info.rows]; offset=(ssize_t) SeekBlob(image,(ssize_t) offset,SEEK_SET); } count=ReadBlob(image,(size_t) runlength[y+z*iris_info.rows], packets); if (EOFBlob(image) != MagickFalse) break; offset+=(ssize_t) runlength[y+z*iris_info.rows]; status=SGIDecode(bytes_per_pixel,(ssize_t) (runlength[y+z*iris_info.rows]/bytes_per_pixel),packets, 1L*iris_info.columns,p+bytes_per_pixel*z); if (status == MagickFalse) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); } p+=(iris_info.columns*4*bytes_per_pixel); } offset=(ssize_t) SeekBlob(image,position,SEEK_SET); } packet_info=RelinquishVirtualMemory(packet_info); runlength=(size_t *) RelinquishMagickMemory(runlength); offsets=(ssize_t *) RelinquishMagickMemory(offsets); } /* Initialize image structure. */ image->matte=iris_info.depth == 4 ? MagickTrue : MagickFalse; image->columns=iris_info.columns; image->rows=iris_info.rows; /* Convert SGI raster image to pixel packets. */ if (image->storage_class == DirectClass) { /* Convert SGI image to DirectClass pixel packets. */ if (bytes_per_pixel == 2) { for (y=0; y < (ssize_t) image->rows; y++) { p=pixels+(image->rows-y-1)*8*image->columns; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelRed(q,ScaleShortToQuantum((unsigned short) ((*(p+0) << 8) | (*(p+1))))); SetPixelGreen(q,ScaleShortToQuantum((unsigned short) ((*(p+2) << 8) | (*(p+3))))); SetPixelBlue(q,ScaleShortToQuantum((unsigned short) ((*(p+4) << 8) | (*(p+5))))); SetPixelOpacity(q,OpaqueOpacity); if (image->matte != MagickFalse) SetPixelAlpha(q,ScaleShortToQuantum((unsigned short) ((*(p+6) << 8) | (*(p+7))))); p+=8; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,image->rows); if (status == MagickFalse) break; } } } else for (y=0; y < (ssize_t) image->rows; y++) { p=pixels+(image->rows-y-1)*4*image->columns; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { SetPixelRed(q,ScaleCharToQuantum(*p)); q->green=ScaleCharToQuantum(*(p+1)); q->blue=ScaleCharToQuantum(*(p+2)); SetPixelOpacity(q,OpaqueOpacity); if (image->matte != MagickFalse) SetPixelAlpha(q,ScaleCharToQuantum(*(p+3))); p+=4; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } } else { /* Create grayscale map. */ if (AcquireImageColormap(image,image->colors) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); /* Convert SGI image to PseudoClass pixel packets. */ if (bytes_per_pixel == 2) { for (y=0; y < (ssize_t) image->rows; y++) { p=pixels+(image->rows-y-1)*8*image->columns; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; indexes=GetAuthenticIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { quantum=(*p << 8); quantum|=(*(p+1)); SetPixelIndex(indexes+x,quantum); p+=8; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,image->rows); if (status == MagickFalse) break; } } } else for (y=0; y < (ssize_t) image->rows; y++) { p=pixels+(image->rows-y-1)*4*image->columns; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; indexes=GetAuthenticIndexQueue(image); for (x=0; x < (ssize_t) image->columns; x++) { SetPixelIndex(indexes+x,*p); p+=4; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } (void) SyncImage(image); } pixel_info=RelinquishVirtualMemory(pixel_info); 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; iris_info.magic=ReadBlobMSBShort(image); if (iris_info.magic == 0x01DA) { /* 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 (iris_info.magic == 0x01DA); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d A V S I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadAVSImage() reads an AVS X 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 ReadAVSImage method is: % % Image *ReadAVSImage(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 *ReadAVSImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; long y; MagickBooleanType status; register long x; register PixelPacket *q; register unsigned char *p; ssize_t count; size_t length; unsigned char *pixels; unsigned long height, width; /* 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=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Read AVS X image. */ width=ReadBlobMSBLong(image); height=ReadBlobMSBLong(image); if ((width == ~0UL) || (height == ~0UL)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); do { /* Convert AVS raster image to pixel packets. */ image->columns=width; image->rows=height; image->depth=8; if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; if (SetImageExtent(image,0,0) == MagickFalse) { InheritException(exception,&image->exception); return(DestroyImageList(image)); } length=(size_t) image->columns; pixels=(unsigned char *) AcquireQuantumMemory(length,4*sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); length*=4*sizeof(*pixels); for (y=0; y < (long) image->rows; y++) { count=ReadBlob(image,length,pixels); if ((size_t) count != length) ThrowReaderException(CorruptImageError,"UnableToReadImageData"); p=pixels; q=SetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*p++)); q->red=ScaleCharToQuantum(*p++); q->green=ScaleCharToQuantum(*p++); q->blue=ScaleCharToQuantum(*p++); if (q->opacity != OpaqueOpacity) image->matte=MagickTrue; q++; } if (SyncImagePixels(image) == MagickFalse) break; if (image->previous == (Image *) NULL) if ((image->progress_monitor != (MagickProgressMonitor) NULL) && (QuantumTick(y,image->rows) != MagickFalse)) { status=image->progress_monitor(LoadImageTag,y,image->rows, image->client_data); if (status == MagickFalse) break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); 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; width=ReadBlobMSBLong(image); height=ReadBlobMSBLong(image); if ((width != ~0UL) && (height != ~0UL)) { /* Allocate next image structure. */ AllocateNextImage(image_info,image); if (GetNextImageInList(image) == (Image *) NULL) { image=DestroyImageList(image); return((Image *) NULL); } image=SyncNextImageInList(image); if (image->progress_monitor != (MagickProgressMonitor) NULL) { status=image->progress_monitor(LoadImagesTag,TellBlob(image), GetBlobSize(image),image->client_data); if (status == MagickFalse) break; } } } while ((width != ~0UL) && (height != ~0UL)); CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d S U N I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ReadSUNImage reads a SUN 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 ReadSUNImage method is: % % Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: Method ReadSUNImage returns a pointer to the image after % reading. A null image is returned if there is a memory shortage or % if the image cannot be read. % % o image_info: Specifies a pointer to a ImageInfo structure. % % o exception: return any errors or warnings in this structure. % % */ static Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception) { Image *image; int bit; long y; register IndexPacket *indexes; register long x; register PixelPacket *q; register long i; register unsigned char *p; size_t bytes_per_image, bytes_per_line, count, sun_data_length; SUNInfo sun_info; unsigned char *sun_data, *sun_pixels; unsigned int index; unsigned int status; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == False) ThrowReaderException(FileOpenError,UnableToOpenFile,image); /* Read SUN raster header. */ (void) memset(&sun_info,0,sizeof(sun_info)); sun_info.magic=ReadBlobMSBLong(image); do { /* Verify SUN identifier. */ if (sun_info.magic != 0x59a66a95) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); sun_info.width=ReadBlobMSBLong(image); sun_info.height=ReadBlobMSBLong(image); sun_info.depth=ReadBlobMSBLong(image); sun_info.length=ReadBlobMSBLong(image); sun_info.type=ReadBlobMSBLong(image); sun_info.maptype=ReadBlobMSBLong(image); sun_info.maplength=ReadBlobMSBLong(image); LogSUNInfo(&sun_info); if (EOFBlob(image)) ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); /* Verify that header values are in positive numeric range of a 32-bit 'int' even though we store them in an unsigned value. */ if ((sun_info.magic | sun_info.width | sun_info.height | sun_info.depth | sun_info.type | sun_info.maptype | sun_info.maplength) & (1U << 31)) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); /* Verify that we support the image sub-type */ if ((sun_info.type != RT_STANDARD) && (sun_info.type != RT_ENCODED) && (sun_info.type != RT_FORMAT_RGB)) ThrowReaderException(CoderError,DataEncodingSchemeIsNotSupported,image); /* Verify that we support the colormap type */ if ((sun_info.maptype != RMT_NONE) && (sun_info.maptype != RMT_EQUAL_RGB)) ThrowReaderException(CoderError,ColormapTypeNotSupported,image); /* Insist that map length is zero if there is no colormap. */ if ((sun_info.maptype == RMT_NONE) && (sun_info.maplength != 0)) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); /* Insist on a supported depth */ if ((sun_info.depth != 1) && (sun_info.depth != 8) && (sun_info.depth != 24) && (sun_info.depth != 32)) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); image->columns=sun_info.width; image->rows=sun_info.height; if (((unsigned long) ((long) image->columns) != image->columns) || ((unsigned long) ((long) image->rows) != image->rows)) ThrowReaderException(CoderError,ImageColumnOrRowSizeIsNotSupported,image); if (CheckImagePixelLimits(image, exception) != MagickPass) ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image); image->depth=sun_info.depth <= 8 ? 8 : QuantumDepth; if (sun_info.depth < 24) { image->colors=sun_info.maplength; if (sun_info.maptype == RMT_NONE) image->colors=1 << sun_info.depth; if (sun_info.maptype == RMT_EQUAL_RGB) image->colors=sun_info.maplength/3; } switch (sun_info.maptype) { case RMT_NONE: { if (sun_info.depth < 24) { /* Create linear color ramp. */ if (!AllocateImageColormap(image,image->colors)) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, image); } break; } case RMT_EQUAL_RGB: { unsigned char *sun_colormap; /* Read SUN raster colormap. */ if (!AllocateImageColormap(image,image->colors)) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, image); sun_colormap=MagickAllocateMemory(unsigned char *,image->colors); if (sun_colormap == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, image); do { if (ReadBlob(image,image->colors,(char *) sun_colormap) != image->colors) { status = MagickFail; break; } for (i=0; i < (long) image->colors; i++) image->colormap[i].red=ScaleCharToQuantum(sun_colormap[i]); if (ReadBlob(image,image->colors,(char *) sun_colormap) != image->colors) { status = MagickFail; break; } for (i=0; i < (long) image->colors; i++) image->colormap[i].green=ScaleCharToQuantum(sun_colormap[i]); if (ReadBlob(image,image->colors,(char *) sun_colormap) != image->colors) { status = MagickFail; break; } for (i=0; i < (long) image->colors; i++) image->colormap[i].blue=ScaleCharToQuantum(sun_colormap[i]); break; } while (1); MagickFreeMemory(sun_colormap); if (MagickFail == status) ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); break; } case RMT_RAW: { unsigned char *sun_colormap; /* Read SUN raster colormap. */ if (!AllocateImageColormap(image,image->colors)) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, image); sun_colormap=MagickAllocateMemory(unsigned char *,sun_info.maplength); if (sun_colormap == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, image); if (ReadBlob(image,sun_info.maplength,(char *) sun_colormap) != sun_info.maplength) status = MagickFail; MagickFreeMemory(sun_colormap); if (MagickFail == status) ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); break; } default: ThrowReaderException(CoderError,ColormapTypeNotSupported,image) } image->matte=(sun_info.depth == 32); image->columns=sun_info.width; image->rows=sun_info.height; image->depth=8; if (sun_info.depth < 8) image->depth=sun_info.depth; /* Compute bytes per line and bytes per image for an unencoded image. "The width of a scan line is always 16-bits, padded when necessary." */ bytes_per_line=MagickArraySize(sun_info.width,sun_info.depth)/8; if ((bytes_per_line != 0) && (sun_info.depth == 1)) bytes_per_line += sun_info.width % 8 ? 1 : 0; if (bytes_per_line != 0) bytes_per_line=RoundUpToAlignment(bytes_per_line,2); bytes_per_image=MagickArraySize(sun_info.height,bytes_per_line); if (bytes_per_line == 0) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); if (bytes_per_image == 0) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); if ((sun_info.type == RT_STANDARD) || (sun_info.type == RT_FORMAT_RGB)) if (bytes_per_image > sun_info.length) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); if (image_info->ping) { CloseBlob(image); return(image); } if (sun_info.type == RT_ENCODED) sun_data_length=(size_t) sun_info.length; else sun_data_length=bytes_per_image; sun_data=MagickAllocateMemory(unsigned char *,sun_data_length); if (sun_data == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); if ((count=ReadBlob(image,sun_data_length,(char *) sun_data)) != sun_data_length) { MagickFreeMemory(sun_data); ThrowReaderException(CorruptImageError,UnableToReadImageData,image); } sun_pixels=sun_data; if (sun_info.type == RT_ENCODED) { /* Read run-length encoded raster pixels (padded to 16-bit boundary). */ sun_pixels=MagickAllocateMemory(unsigned char *,bytes_per_image); if (sun_pixels == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed, image); status &= DecodeImage(sun_data,sun_data_length,sun_pixels,bytes_per_image); MagickFreeMemory(sun_data); if (status != MagickPass) { MagickFreeMemory(sun_pixels); ThrowReaderException(CorruptImageError,UnableToRunlengthDecodeImage,image); } } /* Convert SUN raster image to pixel packets. */ p=sun_pixels; if (sun_info.depth == 1) /* Bilevel */ for (y=0; y < (long) image->rows; y++) { q=SetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; indexes=AccessMutableIndexes(image); for (x=0; x < ((long) image->columns-7); x+=8) { for (bit=7; bit >= 0; bit--) { index=((*p) & (0x01 << bit) ? 0x01 : 0x00); indexes[x+7-bit]=index; q[x+7-bit]=image->colormap[index]; } p++; } if ((image->columns % 8) != 0) { for (bit=7; bit >= (long) (8-(image->columns % 8)); bit--) { index=((*p) & (0x01 << bit) ? 0x01 : 0x00); indexes[x+7-bit]=index; q[x+7-bit]=image->colormap[index]; } p++; } if ((((image->columns/8)+(image->columns % 8 ? 1 : 0)) % 2) != 0) p++; if (!SyncImagePixels(image)) break; if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,exception, LoadImageText,image->filename, image->columns,image->rows)) break; } else if (image->storage_class == PseudoClass) { /* Colormapped */ for (y=0; y < (long) image->rows; y++) { q=SetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; indexes=AccessMutableIndexes(image); for (x=0; x < (long) image->columns; x++) { index=(*p++); VerifyColormapIndex(image,index); indexes[x]=index; q[x]=image->colormap[index]; } if ((image->columns % 2) != 0) p++; if (!SyncImagePixels(image)) break; if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,exception, LoadImageText,image->filename, image->columns,image->rows)) break; } } else { /* (A)BGR or (A)RGB */ for (y=0; y < (long) image->rows; y++) { q=SetImagePixels(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (long) image->columns; x++) { if (image->matte) q->opacity=(Quantum) (MaxRGB-ScaleCharToQuantum(*p++)); if (sun_info.type == RT_STANDARD) { q->blue=ScaleCharToQuantum(*p++); q->green=ScaleCharToQuantum(*p++); q->red=ScaleCharToQuantum(*p++); } else { q->red=ScaleCharToQuantum(*p++); q->green=ScaleCharToQuantum(*p++); q->blue=ScaleCharToQuantum(*p++); } if (image->colors != 0) { q->red=image->colormap[q->red].red; q->green=image->colormap[q->green].green; q->blue=image->colormap[q->blue].blue; } q++; } if (((image->columns % 2) != 0) && (image->matte == False)) p++; if (!SyncImagePixels(image)) break; if (image->previous == (Image *) NULL) if (QuantumTick(y,image->rows)) if (!MagickMonitorFormatted(y,image->rows,exception, LoadImageText,image->filename, image->columns,image->rows)) break; } } MagickFreeMemory(sun_pixels); if (EOFBlob(image)) { ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, image->filename); break; } /* Proceed to next image. */ if (image_info->subrange != 0) if (image->scene >= (image_info->subimage+image_info->subrange-1)) break; sun_info.magic=ReadBlobMSBLong(image); if (sun_info.magic == 0x59a66a95) { /* Allocate next image structure. */ AllocateNextImage(image_info,image); if (image->next == (Image *) NULL) { DestroyImageList(image); return((Image *) NULL); } image=SyncNextImageInList(image); if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image), exception,LoadImagesText, image->filename)) break; } } while (sun_info.magic == 0x59a66a95);