/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + N T G e t T y pe L i s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % NTLoadTypeLists() loads a Windows TrueType fonts. % % The format of the NTLoadTypeLists method is: % % MagickBooleanType NTLoadTypeLists(SplayTreeInfo *type_list) % % A description of each parameter follows: % % o type_list: A linked list of fonts. % */ MagickExport MagickBooleanType NTLoadTypeLists(SplayTreeInfo *type_list, ExceptionInfo *exception) { HKEY reg_key = (HKEY) INVALID_HANDLE_VALUE; LONG res; int list_entries = 0; char buffer[MaxTextExtent], system_root[MaxTextExtent], font_root[MaxTextExtent]; DWORD type, system_root_length; MagickBooleanType status; /* Try to find the right Windows*\CurrentVersion key, the SystemRoot and then the Fonts key */ res = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, ®_key); if (res == ERROR_SUCCESS) { system_root_length=sizeof(system_root)-1; res = RegQueryValueExA(reg_key,"SystemRoot",NULL, &type, (BYTE*) system_root, &system_root_length); } if (res != ERROR_SUCCESS) { res = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ, ®_key); if (res == ERROR_SUCCESS) { system_root_length=sizeof(system_root)-1; res = RegQueryValueExA(reg_key,"SystemRoot",NULL, &type, (BYTE*)system_root, &system_root_length); } } if (res == ERROR_SUCCESS) res = RegOpenKeyExA (reg_key, "Fonts",0, KEY_READ, ®_key); if (res != ERROR_SUCCESS) return(MagickFalse); *font_root='\0'; (void) CopyMagickString(buffer,system_root,MaxTextExtent); (void) ConcatenateMagickString(buffer,"\\fonts\\arial.ttf",MaxTextExtent); if (IsPathAccessible(buffer) != MagickFalse) { (void) CopyMagickString(font_root,system_root,MaxTextExtent); (void) ConcatenateMagickString(font_root,"\\fonts\\",MaxTextExtent); } else { (void) CopyMagickString(font_root,system_root,MaxTextExtent); (void) ConcatenateMagickString(font_root,"\\",MaxTextExtent); } { TypeInfo *type_info; DWORD registry_index = 0, type, value_data_size, value_name_length; char value_data[MaxTextExtent], value_name[MaxTextExtent]; res = ERROR_SUCCESS; while (res != ERROR_NO_MORE_ITEMS) { char *family_extent, token[MaxTextExtent], *pos, *q; value_name_length = sizeof(value_name) - 1; value_data_size = sizeof(value_data) - 1; res = RegEnumValueA ( reg_key, registry_index, value_name, &value_name_length, 0, &type, (BYTE*)value_data, &value_data_size); registry_index++; if (res != ERROR_SUCCESS) continue; if ( (pos = strstr(value_name, " (TrueType)")) == (char*) NULL ) continue; *pos='\0'; /* Remove (TrueType) from string */ type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info)); if (type_info == (TypeInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(type_info,0,sizeof(TypeInfo)); type_info->path=ConstantString("Windows Fonts"); type_info->signature=MagickSignature; /* Name */ (void) CopyMagickString(buffer,value_name,MaxTextExtent); for(pos = buffer; *pos != 0 ; pos++) if (*pos == ' ') *pos = '-'; type_info->name=ConstantString(buffer); /* Fullname */ type_info->description=ConstantString(value_name); /* Format */ type_info->format=ConstantString("truetype"); /* Glyphs */ if (strchr(value_data,'\\') != (char *) NULL) (void) CopyMagickString(buffer,value_data,MaxTextExtent); else { (void) CopyMagickString(buffer,font_root,MaxTextExtent); (void) ConcatenateMagickString(buffer,value_data,MaxTextExtent); } LocaleLower(buffer); type_info->glyphs=ConstantString(buffer); type_info->stretch=NormalStretch; type_info->style=NormalStyle; type_info->weight=400; /* Some fonts are known to require special encodings */ if ( (LocaleCompare(type_info->name, "Symbol") == 0 ) || (LocaleCompare(type_info->name, "Wingdings") == 0 ) || (LocaleCompare(type_info->name, "Wingdings-2") == 0 ) || (LocaleCompare(type_info->name, "Wingdings-3") == 0 ) ) type_info->encoding=ConstantString("AppleRoman"); family_extent=value_name; for (q=value_name; *q != '\0'; ) { GetMagickToken(q,(const char **) &q,token); if (*token == '\0') break; if (LocaleCompare(token,"Italic") == 0) { type_info->style=ItalicStyle; } else if (LocaleCompare(token,"Oblique") == 0) { type_info->style=ObliqueStyle; } else if (LocaleCompare(token,"Bold") == 0) { type_info->weight=700; } else if (LocaleCompare(token,"Thin") == 0) { type_info->weight=100; } else if ( (LocaleCompare(token,"ExtraLight") == 0) || (LocaleCompare(token,"UltraLight") == 0) ) { type_info->weight=200; } else if (LocaleCompare(token,"Light") == 0) { type_info->weight=300; } else if ( (LocaleCompare(token,"Normal") == 0) || (LocaleCompare(token,"Regular") == 0) ) { type_info->weight=400; } else if (LocaleCompare(token,"Medium") == 0) { type_info->weight=500; } else if ( (LocaleCompare(token,"SemiBold") == 0) || (LocaleCompare(token,"DemiBold") == 0) ) { type_info->weight=600; } else if ( (LocaleCompare(token,"ExtraBold") == 0) || (LocaleCompare(token,"UltraBold") == 0) ) { type_info->weight=800; } else if ( (LocaleCompare(token,"Heavy") == 0) || (LocaleCompare(token,"Black") == 0) ) { type_info->weight=900; } else if (LocaleCompare(token,"Condensed") == 0) { type_info->stretch = CondensedStretch; } else if (LocaleCompare(token,"Expanded") == 0) { type_info->stretch = ExpandedStretch; } else if (LocaleCompare(token,"ExtraCondensed") == 0) { type_info->stretch = ExtraCondensedStretch; } else if (LocaleCompare(token,"ExtraExpanded") == 0) { type_info->stretch = ExtraExpandedStretch; } else if (LocaleCompare(token,"SemiCondensed") == 0) { type_info->stretch = SemiCondensedStretch; } else if (LocaleCompare(token,"SemiExpanded") == 0) { type_info->stretch = SemiExpandedStretch; } else if (LocaleCompare(token,"UltraCondensed") == 0) { type_info->stretch = UltraCondensedStretch; } else if (LocaleCompare(token,"UltraExpanded") == 0) { type_info->stretch = UltraExpandedStretch; } else { family_extent=q; } } (void) CopyMagickString(buffer,value_name,family_extent-value_name+1); StripString(buffer); type_info->family=ConstantString(buffer); list_entries++; status=AddValueToSplayTree(type_list,ConstantString(type_info->name), type_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name); } } RegCloseKey ( reg_key ); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e F I T S I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteFITSImage() writes a Flexible Image Transport System image to a % file as gray scale intensities [0..255]. % % The format of the WriteFITSImage method is: % % MagickBooleanType WriteFITSImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteFITSImage(const ImageInfo *image_info, Image *image) { char header[FITSBlocksize], *fits_info; MagickBooleanType status; QuantumInfo *quantum_info; register const PixelPacket *p; size_t length; ssize_t count, offset, y; unsigned char *pixels; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); if (image->colorspace != RGBColorspace) (void) TransformImageColorspace(image,RGBColorspace); /* Allocate image memory. */ fits_info=(char *) AcquireQuantumMemory(FITSBlocksize,sizeof(*fits_info)); if (fits_info == (char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) ResetMagickMemory(fits_info,' ',FITSBlocksize*sizeof(*fits_info)); /* Initialize image header. */ image->depth=GetImageQuantumDepth(image,MagickFalse); quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image); if (quantum_info == (QuantumInfo *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); offset=0; (void) FormatMagickString(header,FITSBlocksize, "SIMPLE = T"); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatMagickString(header,FITSBlocksize,"BITPIX = %10ld", (long) (quantum_info->format == FloatingPointQuantumFormat ? -1 : 1)* image->depth); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatMagickString(header,FITSBlocksize,"NAXIS = %10lu", 2UL); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatMagickString(header,FITSBlocksize,"NAXIS1 = %10lu", (unsigned long) image->columns); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatMagickString(header,FITSBlocksize,"NAXIS2 = %10lu", (unsigned long) image->rows); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatMagickString(header,FITSBlocksize,"BSCALE = %E",1.0); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatMagickString(header,FITSBlocksize,"BZERO = %E", image->depth > 8 ? GetFITSPixelRange(image->depth) : 0.0); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatMagickString(header,FITSBlocksize,"DATAMAX = %E", 1.0*((MagickOffsetType) GetQuantumRange(image->depth))); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) FormatMagickString(header,FITSBlocksize,"DATAMIN = %E",0.0); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; if (image->endian == LSBEndian) { (void) FormatMagickString(header,FITSBlocksize,"XENDIAN = 'SMALL'"); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; } (void) FormatMagickString(header,FITSBlocksize,"HISTORY %.72s", GetMagickVersion((size_t *) NULL)); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) strncpy(header,"END",FITSBlocksize); (void) strncpy(fits_info+offset,header,strlen(header)); offset+=80; (void) WriteBlob(image,FITSBlocksize,(unsigned char *) fits_info); /* Convert image to fits scale PseudoColor class. */ pixels=GetQuantumPixels(quantum_info); length=GetQuantumExtent(image,quantum_info,GrayQuantum); for (y=(ssize_t) image->rows-1; y >= 0; y--) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; length=ExportQuantumPixels(image,(const CacheView *) NULL,quantum_info, GrayQuantum,pixels,&image->exception); if (image->depth == 16) SetFITSUnsignedPixels(image->columns,image->depth,pixels); if (((image->depth == 32) || (image->depth == 64)) && (quantum_info->format != FloatingPointQuantumFormat)) SetFITSUnsignedPixels(image->columns,image->depth,pixels); count=WriteBlob(image,length,pixels); if (count != (ssize_t) length) break; status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } quantum_info=DestroyQuantumInfo(quantum_info); length=(size_t) (FITSBlocksize-TellBlob(image) % FITSBlocksize); if (length != 0) { (void) ResetMagickMemory(fits_info,0,length*sizeof(*fits_info)); (void) WriteBlob(image,length,(unsigned char *) fits_info); } fits_info=DestroyString(fits_info); (void) CloseBlob(image); return(MagickTrue); }
static MagickBooleanType WriteHDRImage(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { char header[MagickPathExtent]; const char *property; MagickBooleanType status; register const Quantum *p; register ssize_t i, x; size_t length; ssize_t count, y; unsigned char pixel[4], *pixels; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); if (IsRGBColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,RGBColorspace,exception); /* Write header. */ (void) ResetMagickMemory(header,' ',MagickPathExtent); length=CopyMagickString(header,"#?RGBE\n",MagickPathExtent); (void) WriteBlob(image,length,(unsigned char *) header); property=GetImageProperty(image,"comment",exception); if ((property != (const char *) NULL) && (strchr(property,'\n') == (char *) NULL)) { count=FormatLocaleString(header,MagickPathExtent,"#%s\n",property); (void) WriteBlob(image,(size_t) count,(unsigned char *) header); } property=GetImageProperty(image,"hdr:exposure",exception); if (property != (const char *) NULL) { count=FormatLocaleString(header,MagickPathExtent,"EXPOSURE=%g\n", strtod(property,(char **) NULL)); (void) WriteBlob(image,(size_t) count,(unsigned char *) header); } if (image->gamma != 0.0) { count=FormatLocaleString(header,MagickPathExtent,"GAMMA=%g\n", image->gamma); (void) WriteBlob(image,(size_t) count,(unsigned char *) header); } count=FormatLocaleString(header,MagickPathExtent, "PRIMARIES=%g %g %g %g %g %g %g %g\n", image->chromaticity.red_primary.x,image->chromaticity.red_primary.y, image->chromaticity.green_primary.x,image->chromaticity.green_primary.y, image->chromaticity.blue_primary.x,image->chromaticity.blue_primary.y, image->chromaticity.white_point.x,image->chromaticity.white_point.y); (void) WriteBlob(image,(size_t) count,(unsigned char *) header); length=CopyMagickString(header,"FORMAT=32-bit_rle_rgbe\n\n",MagickPathExtent); (void) WriteBlob(image,length,(unsigned char *) header); count=FormatLocaleString(header,MagickPathExtent,"-Y %.20g +X %.20g\n", (double) image->rows,(double) image->columns); (void) WriteBlob(image,(size_t) count,(unsigned char *) header); /* Write HDR pixels. */ pixels=(unsigned char *) AcquireQuantumMemory(image->columns+128,4* sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) ResetMagickMemory(pixels,0,4*(image->columns+128)*sizeof(*pixels)); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; if ((image->columns >= 8) && (image->columns <= 0x7ffff)) { pixel[0]=2; pixel[1]=2; pixel[2]=(unsigned char) (image->columns >> 8); pixel[3]=(unsigned char) (image->columns & 0xff); count=WriteBlob(image,4*sizeof(*pixel),pixel); if (count != (ssize_t) (4*sizeof(*pixel))) break; } i=0; for (x=0; x < (ssize_t) image->columns; x++) { double gamma; pixel[0]=0; pixel[1]=0; pixel[2]=0; pixel[3]=0; gamma=QuantumScale*GetPixelRed(image,p); if ((QuantumScale*GetPixelGreen(image,p)) > gamma) gamma=QuantumScale*GetPixelGreen(image,p); if ((QuantumScale*GetPixelBlue(image,p)) > gamma) gamma=QuantumScale*GetPixelBlue(image,p); if (gamma > MagickEpsilon) { int exponent; gamma=frexp(gamma,&exponent)*256.0/gamma; pixel[0]=(unsigned char) (gamma*QuantumScale*GetPixelRed(image,p)); pixel[1]=(unsigned char) (gamma*QuantumScale*GetPixelGreen(image,p)); pixel[2]=(unsigned char) (gamma*QuantumScale*GetPixelBlue(image,p)); pixel[3]=(unsigned char) (exponent+128); } if ((image->columns >= 8) && (image->columns <= 0x7ffff)) { pixels[x]=pixel[0]; pixels[x+image->columns]=pixel[1]; pixels[x+2*image->columns]=pixel[2]; pixels[x+3*image->columns]=pixel[3]; } else { pixels[i++]=pixel[0]; pixels[i++]=pixel[1]; pixels[i++]=pixel[2]; pixels[i++]=pixel[3]; } p+=GetPixelChannels(image); } if ((image->columns >= 8) && (image->columns <= 0x7ffff)) { for (i=0; i < 4; i++) length=HDRWriteRunlengthPixels(image,&pixels[i*image->columns]); } else { count=WriteBlob(image,4*image->columns*sizeof(*pixels),pixels); if (count != (ssize_t) (4*image->columns*sizeof(*pixels))) break; } status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G a u s s J o r d a n E l i m i n a t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GaussJordanElimination() returns a matrix in reduced row echelon form, % while simultaneously reducing and thus solving the augumented results % matrix. % % See also http://en.wikipedia.org/wiki/Gauss-Jordan_elimination % % The format of the GaussJordanElimination method is: % % MagickBooleanType GaussJordanElimination(double **matrix, % double **vectors, const unsigned long rank, const unsigned long nvecs) % % A description of each parameter follows: % % o matrix: the matrix to be reduced, as an 'array of row pointers'. % % o vectors: the additional matrix argumenting the matrix for row reduction. % Producing an 'array of column vectors'. % % o rank: The size of the matrix (both rows and columns). % Also represents the number terms that need to be solved. % % o nvecs: Number of vectors columns, argumenting the above matrix. % Usally 1, but can be more for more complex equation solving. % % Note that the 'matrix' is given as a 'array of row pointers' of rank size. % That is values can be assigned as matrix[row][column] where 'row' is % typically the equation, and 'column' is the term of the equation. % That is the matrix is in the form of a 'row first array'. % % However 'vectors' is a 'array of column pointers' which can have any number % of columns, with each column array the same 'rank' size as 'matrix'. % % This allows for simpler handling of the results, especially is only one % column 'vector' is all that is required to produce the desired solution. % % For example, the 'vectors' can consist of a pointer to a simple array of % doubles. when only one set of simultanious equations is to be solved from % the given set of coefficient weighted terms. % % double **matrix = AcquireMagickMatrix(8UL,8UL); % double coefficents[8]; % ... % GaussJordanElimination(matrix, &coefficents, 8UL, 1UL); % % However by specifing more 'columns' (as an 'array of vector columns', % you can use this function to solve a set of 'separable' equations. % % For example a distortion function where u = U(x,y) v = V(x,y) % And the functions U() and V() have separate coefficents, but are being % generated from a common x,y->u,v data set. % % Another example is generation of a color gradient from a set of colors % at specific coordients, such as a list x,y -> r,g,b,a % (Reference to be added - Anthony) % % You can also use the 'vectors' to generate an inverse of the given 'matrix' % though as a 'column first array' rather than a 'row first array'. For % details see http://en.wikipedia.org/wiki/Gauss-Jordan_elimination % */ MagickExport MagickBooleanType GaussJordanElimination(double **matrix, double **vectors, const unsigned long rank, const unsigned long nvecs) { #define GaussJordanSwap(x,y) \ { \ if ((x) != (y)) \ { \ (x)+=(y); \ (y)=(x)-(y); \ (x)=(x)-(y); \ } \ } double max, scale; long column, *columns, *pivots, row, *rows; register long i, j, k; columns=(long *) AcquireQuantumMemory(rank,sizeof(*columns)); rows=(long *) AcquireQuantumMemory(rank,sizeof(*rows)); pivots=(long *) AcquireQuantumMemory(rank,sizeof(*pivots)); if ((rows == (long *) NULL) || (columns == (long *) NULL) || (pivots == (long *) NULL)) { if (pivots != (long *) NULL) pivots=(long *) RelinquishMagickMemory(pivots); if (columns != (long *) NULL) columns=(long *) RelinquishMagickMemory(columns); if (rows != (long *) NULL) rows=(long *) RelinquishMagickMemory(rows); return(MagickFalse); } (void) ResetMagickMemory(columns,0,rank*sizeof(*columns)); (void) ResetMagickMemory(rows,0,rank*sizeof(*rows)); (void) ResetMagickMemory(pivots,0,rank*sizeof(*pivots)); column=0; row=0; for (i=0; i < (long) rank; i++) { max=0.0; for (j=0; j < (long) rank; j++) if (pivots[j] != 1) { for (k=0; k < (long) rank; k++) if (pivots[k] != 0) { if (pivots[k] > 1) return(MagickFalse); } else if (fabs(matrix[j][k]) >= max) { max=fabs(matrix[j][k]); row=j; column=k; } } pivots[column]++; if (row != column) { for (k=0; k < (long) rank; k++) GaussJordanSwap(matrix[row][k],matrix[column][k]); for (k=0; k < (long) nvecs; k++) GaussJordanSwap(vectors[k][row],vectors[k][column]); } rows[i]=row; columns[i]=column; if (matrix[column][column] == 0.0) return(MagickFalse); /* sigularity */ scale=1.0/matrix[column][column]; matrix[column][column]=1.0; for (j=0; j < (long) rank; j++) matrix[column][j]*=scale; for (j=0; j < (long) nvecs; j++) vectors[j][column]*=scale; for (j=0; j < (long) rank; j++) if (j != column) { scale=matrix[j][column]; matrix[j][column]=0.0; for (k=0; k < (long) rank; k++) matrix[j][k]-=scale*matrix[column][k]; for (k=0; k < (long) nvecs; k++) vectors[k][j]-=scale*vectors[k][column]; } } for (j=(long) rank-1; j >= 0; j--) if (columns[j] != rows[j]) for (i=0; i < (long) rank; i++) GaussJordanSwap(matrix[i][rows[j]],matrix[i][columns[j]]); pivots=(long *) RelinquishMagickMemory(pivots); rows=(long *) RelinquishMagickMemory(rows); columns=(long *) RelinquishMagickMemory(columns); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % L o a d C o d e r L i s t s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadCoderLists() loads one or more coder configuration file which % provides a mapping between coder attributes and a coder name. % % The format of the LoadCoderLists coder is: % % MagickBooleanType LoadCoderLists(const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: the font file name. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType LoadCoderLists(const char *filename, ExceptionInfo *exception) { const StringInfo *option; LinkedListInfo *options; MagickStatusType status; register ssize_t i; /* Load built-in coder map. */ status=MagickFalse; if (coder_list == (SplayTreeInfo *) NULL) { coder_list=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, DestroyCoderNode); if (coder_list == (SplayTreeInfo *) NULL) { ThrowFileException(exception,ResourceLimitError, "MemoryAllocationFailed",filename); return(MagickFalse); } } for (i=0; i < (ssize_t) (sizeof(CoderMap)/sizeof(*CoderMap)); i++) { CoderInfo *coder_info; register const CoderMapInfo *p; p=CoderMap+i; coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info)); if (coder_info == (CoderInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",coder_info->name); continue; } (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info)); coder_info->path=(char *) "[built-in]"; coder_info->magick=(char *) p->magick; coder_info->name=(char *) p->name; coder_info->exempt=MagickTrue; coder_info->signature=MagickSignature; status=AddValueToSplayTree(coder_list,ConstantString(coder_info->magick), coder_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",coder_info->name); } /* Load external coder map. */ options=GetConfigureOptions(filename,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); while (option != (const StringInfo *) NULL) { status|=LoadCoderList((const char *) GetStringInfoDatum(option), GetStringInfoPath(option),0,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); } options=DestroyConfigureOptions(options); return(status != 0 ? MagickTrue : MagickFalse); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d C A L S I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadCALSImage() reads an CALS Raster Group 1 image format 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 ReadCALSImage method is: % % Image *ReadCALSImage(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 *ReadCALSImage(const ImageInfo *image_info, ExceptionInfo *exception) { char filename[MaxTextExtent], header[129], message[MaxTextExtent]; FILE *file; Image *image; ImageInfo *read_info; int c, unique_file; MagickBooleanType status; register ssize_t i; unsigned long density, direction, height, orientation, pel_path, type, 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=AcquireImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } /* Read CALS header. */ (void) ResetMagickMemory(header,0,sizeof(header)); density=0; direction=0; orientation=1; pel_path=0; type=1; width=0; height=0; for (i=0; i < 16; i++) { if (ReadBlob(image,128,(unsigned char *) header) != 128) break; switch (*header) { case 'R': case 'r': { if (LocaleNCompare(header,"rdensty:",8) == 0) { (void) sscanf(header+8,"%lu",&density); break; } if (LocaleNCompare(header,"rpelcnt:",8) == 0) { (void) sscanf(header+8,"%lu,%lu",&width,&height); break; } if (LocaleNCompare(header,"rorient:",8) == 0) { (void) sscanf(header+8,"%lu,%lu",&pel_path,&direction); if (pel_path == 90) orientation=5; else if (pel_path == 180) orientation=3; else if (pel_path == 270) orientation=7; if (direction == 90) orientation++; break; } if (LocaleNCompare(header,"rtype:",6) == 0) { (void) sscanf(header+6,"%lu",&type); break; } break; } } } /* Read CALS pixels. */ 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"); while ((c=ReadBlobByte(image)) != EOF) (void) fputc(c,file); (void) fclose(file); (void) CloseBlob(image); image=DestroyImage(image); read_info=CloneImageInfo(image_info); SetImageInfoBlob(read_info,(void *) NULL,0); (void) FormatLocaleString(read_info->filename,MaxTextExtent,"group4:%s", filename); (void) FormatLocaleString(message,MaxTextExtent,"%lux%lu",width,height); read_info->size=ConstantString(message); (void) FormatLocaleString(message,MaxTextExtent,"%lu",density); read_info->density=ConstantString(message); read_info->orientation=(OrientationType) orientation; 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,"CALS",MaxTextExtent); } read_info=DestroyImageInfo(read_info); (void) RelinquishUniqueFileResource(filename); return(image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + F i n a l i z e S i g n a t u r e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % FinalizeSignature() finalizes the Signature message accumulator computation. % % The format of the FinalizeSignature method is: % % FinalizeSignature(SignatureInfo *signature_info) % % A description of each parameter follows: % % o signature_info: the address of a structure of type SignatureInfo. % */ MagickExport void FinalizeSignature(SignatureInfo *signature_info) { register ssize_t i; register unsigned char *q; register unsigned int *p; unsigned char *datum; unsigned int count, high_order, low_order; /* Add padding and return the message accumulator. */ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(signature_info != (SignatureInfo *) NULL); assert(signature_info->signature == MagickSignature); low_order=signature_info->low_order; high_order=signature_info->high_order; count=((low_order >> 3) & 0x3f); datum=GetStringInfoDatum(signature_info->message); datum[count++]=(unsigned char) 0x80; if (count <= (unsigned int) (GetStringInfoLength(signature_info->message)-8)) (void) ResetMagickMemory(datum+count,0,GetStringInfoLength( signature_info->message)-8-count); else { (void) ResetMagickMemory(datum+count,0,GetStringInfoLength( signature_info->message)-count); TransformSignature(signature_info); (void) ResetMagickMemory(datum,0,GetStringInfoLength( signature_info->message)-8); } datum[56]=(unsigned char) (high_order >> 24); datum[57]=(unsigned char) (high_order >> 16); datum[58]=(unsigned char) (high_order >> 8); datum[59]=(unsigned char) high_order; datum[60]=(unsigned char) (low_order >> 24); datum[61]=(unsigned char) (low_order >> 16); datum[62]=(unsigned char) (low_order >> 8); datum[63]=(unsigned char) low_order; TransformSignature(signature_info); p=signature_info->accumulator; q=GetStringInfoDatum(signature_info->digest); for (i=0; i < (SignatureDigestsize/4); i++) { *q++=(unsigned char) ((*p >> 24) & 0xff); *q++=(unsigned char) ((*p >> 16) & 0xff); *q++=(unsigned char) ((*p >> 8) & 0xff); *q++=(unsigned char) (*p & 0xff); p++; } /* Reset working registers. */ count=0; high_order=0; low_order=0; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e J P 2 I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteJP2Image() writes an image in the JPEG 2000 image format. % % JP2 support originally written by Nathan Brown, [email protected] % % The format of the WriteJP2Image method is: % % MagickBooleanType WriteJP2Image(const ImageInfo *image_info, % Image *image,ExceptionInfo *exception) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType WriteJP2Image(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { char *key, magick[MaxTextExtent], *options; const char *option; jas_image_cmptparm_t component_info[4]; jas_image_t *jp2_image; jas_matrix_t *pixels[4]; jas_stream_t *jp2_stream; MagickBooleanType status; QuantumAny range; register const Quantum *p; register ssize_t i, x; size_t number_components; ssize_t format, y; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); /* Initialize JPEG 2000 API. */ if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,sRGBColorspace,exception); jp2_stream=JP2StreamManager(image); if (jp2_stream == (jas_stream_t *) NULL) ThrowWriterException(DelegateError,"UnableToManageJP2Stream"); number_components=image->alpha_trait ? 4UL : 3UL; if (IsGrayColorspace(image->colorspace) != MagickFalse) number_components=1; if ((image->columns != (unsigned int) image->columns) || (image->rows != (unsigned int) image->rows)) ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit"); (void) ResetMagickMemory(&component_info,0,sizeof(component_info)); for (i=0; i < (ssize_t) number_components; i++) { component_info[i].tlx=0; component_info[i].tly=0; component_info[i].hstep=1; component_info[i].vstep=1; component_info[i].width=(unsigned int) image->columns; component_info[i].height=(unsigned int) image->rows; component_info[i].prec=(int) MagickMax(MagickMin(image->depth,16),2); component_info[i].sgnd=MagickFalse; } jp2_image=jas_image_create((int) number_components,component_info, JAS_CLRSPC_UNKNOWN); if (jp2_image == (jas_image_t *) NULL) ThrowWriterException(DelegateError,"UnableToCreateImage"); switch (image->colorspace) { case RGBColorspace: case sRGBColorspace: { /* RGB colorspace. */ jas_image_setclrspc(jp2_image,JAS_CLRSPC_SRGB); jas_image_setcmpttype(jp2_image,0, (jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); jas_image_setcmpttype(jp2_image,1, (jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); jas_image_setcmpttype(jp2_image,2, (jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); if (number_components == 4) jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY); break; } case GRAYColorspace: { /* Grayscale colorspace. */ jas_image_setclrspc(jp2_image,JAS_CLRSPC_SGRAY); jas_image_setcmpttype(jp2_image,0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y)); break; } case YCbCrColorspace: { /* YCbCr colorspace. */ jas_image_setclrspc(jp2_image,JAS_CLRSPC_SYCBCR); jas_image_setcmpttype(jp2_image,0,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(0)); jas_image_setcmpttype(jp2_image,1,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(1)); jas_image_setcmpttype(jp2_image,2,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(2)); if (number_components == 4) jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY); break; } case XYZColorspace: { /* XYZ colorspace. */ jas_image_setclrspc(jp2_image,JAS_CLRSPC_CIEXYZ); jas_image_setcmpttype(jp2_image,0,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(0)); jas_image_setcmpttype(jp2_image,1,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(1)); jas_image_setcmpttype(jp2_image,2,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(2)); if (number_components == 4) jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY); break; } case LabColorspace: { /* Lab colorspace. */ jas_image_setclrspc(jp2_image,JAS_CLRSPC_CIELAB); jas_image_setcmpttype(jp2_image,0,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(0)); jas_image_setcmpttype(jp2_image,1,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(1)); jas_image_setcmpttype(jp2_image,2,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(2)); if (number_components == 4) jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY); break; } default: { /* Unknow. */ jas_image_setclrspc(jp2_image,JAS_CLRSPC_UNKNOWN); jas_image_setcmpttype(jp2_image,0,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(0)); jas_image_setcmpttype(jp2_image,1,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(1)); jas_image_setcmpttype(jp2_image,2,(jas_image_cmpttype_t) JAS_IMAGE_CT_COLOR(2)); if (number_components == 4) jas_image_setcmpttype(jp2_image,3,JAS_IMAGE_CT_OPACITY); break; } } /* Convert to JPEG 2000 pixels. */ for (i=0; i < (ssize_t) number_components; i++) { pixels[i]=jas_matrix_create(1,(int) image->columns); if (pixels[i] == (jas_matrix_t *) NULL) { for (x=0; x < i; x++) jas_matrix_destroy(pixels[x]); jas_image_destroy(jp2_image); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } } range=GetQuantumRange((size_t) component_info[0].prec); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { if (number_components == 1) jas_matrix_setv(pixels[0],x,(jas_seqent_t) ScaleQuantumToAny( GetPixelIntensity(image,p),range)); else { jas_matrix_setv(pixels[0],x,(jas_seqent_t) ScaleQuantumToAny( GetPixelRed(image,p),range)); jas_matrix_setv(pixels[1],x,(jas_seqent_t) ScaleQuantumToAny( GetPixelGreen(image,p),range)); jas_matrix_setv(pixels[2],x,(jas_seqent_t) ScaleQuantumToAny( GetPixelBlue(image,p),range)); if (number_components > 3) jas_matrix_setv(pixels[3],x,(jas_seqent_t) ScaleQuantumToAny( GetPixelAlpha(image,p),range)); } p+=GetPixelChannels(image); } for (i=0; i < (ssize_t) number_components; i++) (void) jas_image_writecmpt(jp2_image,(short) i,0,(unsigned int) y, (unsigned int) image->columns,1,pixels[i]); status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } (void) CopyMagickString(magick,image_info->magick,MaxTextExtent); if (LocaleCompare(magick,"J2C") == 0) (void) CopyMagickString(magick,"JPC",MaxTextExtent); LocaleLower(magick); format=jas_image_strtofmt(magick); options=(char *) NULL; ResetImageOptionIterator(image_info); key=GetNextImageOption(image_info); for ( ; key != (char *) NULL; key=GetNextImageOption(image_info)) { option=GetImageOption(image_info,key); if (option == (const char *) NULL) continue; if (LocaleNCompare(key,"jp2:",4) == 0) { (void) ConcatenateString(&options,key+4); if (*option != '\0') { (void) ConcatenateString(&options,"="); (void) ConcatenateString(&options,option); } (void) ConcatenateString(&options," "); } } option=GetImageOption(image_info,"jp2:rate"); if ((option == (const char *) NULL) && (image_info->compression != LosslessJPEGCompression) && (image->quality != UndefinedCompressionQuality) && ((double) image->quality <= 99.5) && ((image->rows*image->columns) > 2500)) { char option[MaxTextExtent]; double alpha, header_size, number_pixels, rate, target_size; alpha=115.0-image->quality; rate=100.0/(alpha*alpha); header_size=550.0; header_size+=(number_components-1)*142; number_pixels=(double) image->rows*image->columns*number_components* (GetImageQuantumDepth(image,MagickTrue)/8); target_size=(number_pixels*rate)+header_size; rate=target_size/number_pixels; (void) FormatLocaleString(option,MaxTextExtent,"rate=%g",rate); (void) ConcatenateString(&options,option); } status=jas_image_encode(jp2_image,jp2_stream,format,options) != 0 ? MagickTrue : MagickFalse; if (options != (char *) NULL) options=DestroyString(options); (void) jas_stream_close(jp2_stream); for (i=0; i < (ssize_t) number_components; i++) jas_matrix_destroy(pixels[i]); jas_image_destroy(jp2_image); if (status != MagickFalse) ThrowWriterException(DelegateError,"UnableToEncodeImageFile"); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e V I C A R I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteVICARImage() writes an image in the VICAR rasterfile format. % Vicar files contain a text header, followed by one or more planes of binary % grayscale image data. Vicar files are designed to allow many planes to be % stacked together to form image cubes. This method only writes a single % grayscale plane. % % WriteVICARImage was written contributed by [email protected]. % % The format of the WriteVICARImage method is: % % MagickBooleanType WriteVICARImage(const ImageInfo *image_info, % Image *image) % % A description of each parameter follows. % % o image_info: the image info. % % o image: The image. % */ static MagickBooleanType WriteVICARImage(const ImageInfo *image_info, Image *image) { char header[MaxTextExtent]; int y; MagickBooleanType status; QuantumInfo *quantum_info; register const PixelPacket *p; size_t length; ssize_t count; unsigned char *pixels; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,sRGBColorspace); /* Write header. */ (void) ResetMagickMemory(header,' ',MaxTextExtent); (void) FormatLocaleString(header,MaxTextExtent, "LBLSIZE=%.20g FORMAT='BYTE' TYPE='IMAGE' BUFSIZE=20000 DIM=2 EOL=0 " "RECSIZE=%.20g ORG='BSQ' NL=%.20g NS=%.20g NB=1 N1=0 N2=0 N3=0 N4=0 NBB=0 " "NLB=0 TASK='ImageMagick'",(double) MaxTextExtent,(double) image->columns, (double) image->rows,(double) image->columns); (void) WriteBlob(image,MaxTextExtent,(unsigned char *) header); /* Write VICAR pixels. */ image->depth=8; quantum_info=AcquireQuantumInfo(image_info,image); if (quantum_info == (QuantumInfo *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); pixels=GetQuantumPixels(quantum_info); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; length=ExportQuantumPixels(image,(const CacheView *) NULL,quantum_info, GrayQuantum,pixels,&image->exception); count=WriteBlob(image,length,pixels); if (count != (ssize_t) length) break; status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } quantum_info=DestroyQuantumInfo(quantum_info); (void) CloseBlob(image); return(MagickTrue); }
static MagickBooleanType WriteSGIImage(const ImageInfo *image_info,Image *image) { CompressionType compression; const char *value; MagickBooleanType status; MagickOffsetType scene; MagickSizeType number_pixels; MemoryInfo *pixel_info; SGIInfo iris_info; register const PixelPacket *p; register ssize_t i, x; register unsigned char *q; ssize_t y, z; unsigned char *pixels, *packets; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); if ((image->columns > 65535UL) || (image->rows > 65535UL)) ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit"); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); scene=0; do { /* Initialize SGI raster file header. */ (void) TransformImageColorspace(image,sRGBColorspace); (void) ResetMagickMemory(&iris_info,0,sizeof(iris_info)); iris_info.magic=0x01DA; compression=image->compression; if (image_info->compression != UndefinedCompression) compression=image_info->compression; if (image->depth > 8) compression=NoCompression; if (compression == NoCompression) iris_info.storage=(unsigned char) 0x00; else iris_info.storage=(unsigned char) 0x01; iris_info.bytes_per_pixel=(unsigned char) (image->depth > 8 ? 2 : 1); iris_info.dimension=3; iris_info.columns=(unsigned short) image->columns; iris_info.rows=(unsigned short) image->rows; if (image->matte != MagickFalse) iris_info.depth=4; else { if ((image_info->type != TrueColorType) && (SetImageGray(image,&image->exception) != MagickFalse)) { iris_info.dimension=2; iris_info.depth=1; } else iris_info.depth=3; } iris_info.minimum_value=0; iris_info.maximum_value=(size_t) (image->depth <= 8 ? 1UL*ScaleQuantumToChar(QuantumRange) : 1UL*ScaleQuantumToShort(QuantumRange)); /* Write SGI header. */ (void) WriteBlobMSBShort(image,iris_info.magic); (void) WriteBlobByte(image,iris_info.storage); (void) WriteBlobByte(image,iris_info.bytes_per_pixel); (void) WriteBlobMSBShort(image,iris_info.dimension); (void) WriteBlobMSBShort(image,iris_info.columns); (void) WriteBlobMSBShort(image,iris_info.rows); (void) WriteBlobMSBShort(image,iris_info.depth); (void) WriteBlobMSBLong(image,(unsigned int) iris_info.minimum_value); (void) WriteBlobMSBLong(image,(unsigned int) iris_info.maximum_value); (void) WriteBlobMSBLong(image,(unsigned int) iris_info.sans); value=GetImageProperty(image,"label"); if (value != (const char *) NULL) (void) CopyMagickString(iris_info.name,value,sizeof(iris_info.name)); (void) WriteBlob(image,sizeof(iris_info.name),(unsigned char *) iris_info.name); (void) WriteBlobMSBLong(image,(unsigned int) iris_info.pixel_format); (void) WriteBlob(image,sizeof(iris_info.filler),iris_info.filler); /* Allocate SGI pixels. */ number_pixels=(MagickSizeType) image->columns*image->rows; if ((4*iris_info.bytes_per_pixel*number_pixels) != ((MagickSizeType) (size_t) (4*iris_info.bytes_per_pixel*number_pixels))) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); pixel_info=AcquireVirtualMemory((size_t) number_pixels,4* iris_info.bytes_per_pixel*sizeof(*pixels)); if (pixel_info == (MemoryInfo *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info); /* Convert image pixels to uncompressed SGI pixels. */ for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; if (image->depth <= 8) for (x=0; x < (ssize_t) image->columns; x++) { register unsigned char *q; q=(unsigned char *) pixels; q+=((iris_info.rows-1)-y)*(4*iris_info.columns)+4*x; *q++=ScaleQuantumToChar(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(p)); *q++=ScaleQuantumToChar(GetPixelAlpha(p)); p++; } else for (x=0; x < (ssize_t) image->columns; x++) { register unsigned short *q; q=(unsigned short *) pixels; q+=((iris_info.rows-1)-y)*(4*iris_info.columns)+4*x; *q++=ScaleQuantumToShort(GetPixelRed(p)); *q++=ScaleQuantumToShort(GetPixelGreen(p)); *q++=ScaleQuantumToShort(GetPixelBlue(p)); *q++=ScaleQuantumToShort(GetPixelAlpha(p)); p++; } if (image->previous == (Image *) NULL) { status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } switch (compression) { case NoCompression: { /* Write uncompressed SGI pixels. */ for (z=0; z < (ssize_t) iris_info.depth; z++) { for (y=0; y < (ssize_t) iris_info.rows; y++) { if (image->depth <= 8) for (x=0; x < (ssize_t) iris_info.columns; x++) { register unsigned char *q; q=(unsigned char *) pixels; q+=y*(4*iris_info.columns)+4*x+z; (void) WriteBlobByte(image,*q); } else for (x=0; x < (ssize_t) iris_info.columns; x++) { register unsigned short *q; q=(unsigned short *) pixels; q+=y*(4*iris_info.columns)+4*x+z; (void) WriteBlobMSBShort(image,*q); } } } break; } default: { MemoryInfo *packet_info; size_t length, number_packets, *runlength; ssize_t offset, *offsets; /* Convert SGI uncompressed pixels. */ offsets=(ssize_t *) AcquireQuantumMemory(iris_info.rows, iris_info.depth*sizeof(*offsets)); runlength=(size_t *) AcquireQuantumMemory(iris_info.rows, iris_info.depth*sizeof(*runlength)); packet_info=AcquireVirtualMemory((2*(size_t) iris_info.columns+10)* image->rows,4*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); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } packets=(unsigned char *) GetVirtualMemoryBlob(packet_info); offset=512+4*2*((ssize_t) iris_info.rows*iris_info.depth); number_packets=0; q=pixels; for (y=0; y < (ssize_t) iris_info.rows; y++) { for (z=0; z < (ssize_t) iris_info.depth; z++) { length=SGIEncode(q+z,(size_t) iris_info.columns,packets+ number_packets); number_packets+=length; offsets[y+z*iris_info.rows]=offset; runlength[y+z*iris_info.rows]=(size_t) length; offset+=(ssize_t) length; } q+=(iris_info.columns*4); } /* Write out line start and length tables and runlength-encoded pixels. */ for (i=0; i < (ssize_t) (iris_info.rows*iris_info.depth); i++) (void) WriteBlobMSBLong(image,(unsigned int) offsets[i]); for (i=0; i < (ssize_t) (iris_info.rows*iris_info.depth); i++) (void) WriteBlobMSBLong(image,(unsigned int) runlength[i]); (void) WriteBlob(image,number_packets,packets); /* Relinquish resources. */ offsets=(ssize_t *) RelinquishMagickMemory(offsets); runlength=(size_t *) RelinquishMagickMemory(runlength); packet_info=RelinquishVirtualMemory(packet_info); break; } } pixel_info=RelinquishVirtualMemory(pixel_info); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) CloseBlob(image); return(MagickTrue); }
MagickExport Image *OilPaintImage(const Image *image,const double radius, ExceptionInfo *exception) { #define NumberPaintBins 256 #define OilPaintImageTag "OilPaint/Image" CacheView *image_view, *paint_view; Image *paint_image; MagickBooleanType status; MagickOffsetType progress; size_t **restrict histograms, width; ssize_t y; /* Initialize painted image attributes. */ assert(image != (const Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); width=GetOptimalKernelWidth2D(radius,0.5); paint_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception); if (paint_image == (Image *) NULL) return((Image *) NULL); if (SetImageStorageClass(paint_image,DirectClass) == MagickFalse) { InheritException(exception,&paint_image->exception); paint_image=DestroyImage(paint_image); return((Image *) NULL); } histograms=AcquireHistogramThreadSet(NumberPaintBins); if (histograms == (size_t **) NULL) { paint_image=DestroyImage(paint_image); ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); } /* Oil paint image. */ status=MagickTrue; progress=0; image_view=AcquireVirtualCacheView(image,exception); paint_view=AcquireAuthenticCacheView(paint_image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static,4) shared(progress,status) \ IsConcurrentDos(image->columns,image->rows,64) #endif for (y=0; y < (ssize_t) image->rows; y++) { register const IndexPacket *restrict indexes; register const PixelPacket *restrict p; register IndexPacket *restrict paint_indexes; register ssize_t x; register PixelPacket *restrict q; register size_t *histogram; if (status == MagickFalse) continue; p=GetCacheViewVirtualPixels(image_view,-((ssize_t) width/2L),y-(ssize_t) (width/2L),image->columns+width,width,exception); q=QueueCacheViewAuthenticPixels(paint_view,0,y,paint_image->columns,1, exception); if ((p == (const PixelPacket *) NULL) || (q == (PixelPacket *) NULL)) { status=MagickFalse; continue; } indexes=GetCacheViewVirtualIndexQueue(image_view); paint_indexes=GetCacheViewAuthenticIndexQueue(paint_view); histogram=histograms[GetOpenMPThreadId()]; for (x=0; x < (ssize_t) image->columns; x++) { register ssize_t i, u; size_t count; ssize_t j, k, v; /* Assign most frequent color. */ i=0; j=0; count=0; (void) ResetMagickMemory(histogram,0,NumberPaintBins*sizeof(*histogram)); for (v=0; v < (ssize_t) width; v++) { for (u=0; u < (ssize_t) width; u++) { k=(ssize_t) ScaleQuantumToChar(PixelIntensityToQuantum(p+u+i)); histogram[k]++; if (histogram[k] > count) { j=i+u; count=histogram[k]; } } i+=(ssize_t) (image->columns+width); } *q=(*(p+j)); if (image->colorspace == CMYKColorspace) SetPixelIndex(paint_indexes+x,GetPixelIndex( indexes+x+j)); p++; q++; } if (SyncCacheViewAuthenticPixels(paint_view,exception) == MagickFalse) status=MagickFalse; if (image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_OilPaintImage) #endif proceed=SetImageProgress(image,OilPaintImageTag,progress++,image->rows); if (proceed == MagickFalse) status=MagickFalse; } } paint_view=DestroyCacheView(paint_view); image_view=DestroyCacheView(image_view); histograms=DestroyHistogramThreadSet(histograms); if (status == MagickFalse) paint_image=DestroyImage(paint_image); return(paint_image); }
MagickExport MagickBooleanType GradientImage(Image *image, const GradientType type,const SpreadMethod method, const PixelPacket *start_color,const PixelPacket *stop_color) { DrawInfo *draw_info; GradientInfo *gradient; MagickBooleanType status; register ssize_t i; /* Set gradient start-stop end points. */ assert(image != (const Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(start_color != (const PixelPacket *) NULL); assert(stop_color != (const PixelPacket *) NULL); draw_info=AcquireDrawInfo(); gradient=(&draw_info->gradient); gradient->type=type; gradient->bounding_box.width=image->columns; gradient->bounding_box.height=image->rows; gradient->gradient_vector.x2=(double) image->columns-1.0; gradient->gradient_vector.y2=(double) image->rows-1.0; if ((type == LinearGradient) && (gradient->gradient_vector.y2 != 0.0)) gradient->gradient_vector.x2=0.0; gradient->center.x=(double) gradient->gradient_vector.x2/2.0; gradient->center.y=(double) gradient->gradient_vector.y2/2.0; gradient->radius=MagickMax(gradient->center.x,gradient->center.y); gradient->spread=method; /* Define the gradient to fill between the stops. */ gradient->number_stops=2; gradient->stops=(StopInfo *) AcquireQuantumMemory(gradient->number_stops, sizeof(*gradient->stops)); if (gradient->stops == (StopInfo *) NULL) ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", image->filename); (void) ResetMagickMemory(gradient->stops,0,gradient->number_stops* sizeof(*gradient->stops)); for (i=0; i < (ssize_t) gradient->number_stops; i++) GetMagickPixelPacket(image,&gradient->stops[i].color); SetMagickPixelPacket(image,start_color,(IndexPacket *) NULL, &gradient->stops[0].color); gradient->stops[0].offset=0.0; SetMagickPixelPacket(image,stop_color,(IndexPacket *) NULL, &gradient->stops[1].color); gradient->stops[1].offset=1.0; /* Draw a gradient on the image. */ status=DrawGradientImage(image,draw_info); draw_info=DestroyDrawInfo(draw_info); if ((start_color->opacity == OpaqueOpacity) && (stop_color->opacity == OpaqueOpacity)) image->matte=MagickFalse; if ((IsGrayPixel(start_color) != MagickFalse) && (IsGrayPixel(stop_color) != MagickFalse)) image->type=GrayscaleType; return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % I m a g e T o H B i t m a p % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ImageToHBITMAP() creates a Windows HBITMAP from an image. % % The format of the ImageToHBITMAP method is: % % HBITMAP ImageToHBITMAP(Image *image) % % A description of each parameter follows: % % o image: the image to convert. % */ MagickExport void *ImageToHBITMAP(Image *image) { BITMAP bitmap; ExceptionInfo *exception; HANDLE bitmap_bitsH; HBITMAP bitmapH; register ssize_t x; register const PixelPacket *p; register RGBQUAD *q; RGBQUAD *bitmap_bits; size_t length; ssize_t y; (void) ResetMagickMemory(&bitmap,0,sizeof(bitmap)); bitmap.bmType=0; bitmap.bmWidth=(LONG) image->columns; bitmap.bmHeight=(LONG) image->rows; bitmap.bmWidthBytes=4*bitmap.bmWidth; bitmap.bmPlanes=1; bitmap.bmBitsPixel=32; bitmap.bmBits=NULL; length=bitmap.bmWidthBytes*bitmap.bmHeight; bitmap_bitsH=(HANDLE) GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,length); if (bitmap_bitsH == NULL) { char *message; message=GetExceptionMessage(errno); (void) ThrowMagickException(&image->exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",message); message=DestroyString(message); return(NULL); } bitmap_bits=(RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH); q=bitmap_bits; if (bitmap.bmBits == NULL) bitmap.bmBits=bitmap_bits; (void) TransformImageColorspace(image,sRGBColorspace); exception=(&image->exception); for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { q->rgbRed=ScaleQuantumToChar(GetPixelRed(p)); q->rgbGreen=ScaleQuantumToChar(GetPixelGreen(p)); q->rgbBlue=ScaleQuantumToChar(GetPixelBlue(p)); q->rgbReserved=0; p++; q++; } } bitmap.bmBits=bitmap_bits; bitmapH=CreateBitmapIndirect(&bitmap); if (bitmapH == NULL) { char *message; message=GetExceptionMessage(errno); (void) ThrowMagickException(&image->exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",message); message=DestroyString(message); } GlobalUnlock((HGLOBAL) bitmap_bitsH); GlobalFree((HGLOBAL) bitmap_bitsH); return((void *) bitmapH); }
static MagickBooleanType ForwardFourier(const FourierInfo *fourier_info, Image *image,double *magnitude,double *phase,ExceptionInfo *exception) { CacheView *magnitude_view, *phase_view; double *magnitude_source, *phase_source; Image *magnitude_image, *phase_image; MagickBooleanType status; register IndexPacket *indexes; register ssize_t x; register PixelPacket *q; ssize_t i, y; magnitude_image=GetFirstImageInList(image); phase_image=GetNextImageInList(image); if (phase_image == (Image *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(),ImageError, "ImageSequenceRequired","`%s'",image->filename); return(MagickFalse); } /* Create "Fourier Transform" image from constituent arrays. */ magnitude_source=(double *) AcquireQuantumMemory((size_t) fourier_info->height,fourier_info->width*sizeof(*magnitude_source)); if (magnitude_source == (double *) NULL) return(MagickFalse); (void) ResetMagickMemory(magnitude_source,0,fourier_info->height* fourier_info->width*sizeof(*magnitude_source)); phase_source=(double *) AcquireQuantumMemory((size_t) fourier_info->height, fourier_info->width*sizeof(*phase_source)); if (phase_source == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); magnitude_source=(double *) RelinquishMagickMemory(magnitude_source); return(MagickFalse); } status=ForwardQuadrantSwap(fourier_info->height,fourier_info->height, magnitude,magnitude_source); if (status != MagickFalse) status=ForwardQuadrantSwap(fourier_info->height,fourier_info->height,phase, phase_source); CorrectPhaseLHS(fourier_info->height,fourier_info->height,phase_source); if (fourier_info->modulus != MagickFalse) { i=0L; for (y=0L; y < (ssize_t) fourier_info->height; y++) for (x=0L; x < (ssize_t) fourier_info->width; x++) { phase_source[i]/=(2.0*MagickPI); phase_source[i]+=0.5; i++; } } magnitude_view=AcquireCacheView(magnitude_image); phase_view=AcquireCacheView(phase_image); i=0L; for (y=0L; y < (ssize_t) fourier_info->height; y++) { q=GetCacheViewAuthenticPixels(magnitude_view,0L,y,fourier_info->height,1UL, exception); if (q == (PixelPacket *) NULL) break; indexes=GetCacheViewAuthenticIndexQueue(magnitude_view); for (x=0L; x < (ssize_t) fourier_info->width; x++) { switch (fourier_info->channel) { case RedChannel: default: { SetPixelRed(q,ClampToQuantum(QuantumRange* magnitude_source[i])); break; } case GreenChannel: { SetPixelGreen(q,ClampToQuantum(QuantumRange* magnitude_source[i])); break; } case BlueChannel: { SetPixelBlue(q,ClampToQuantum(QuantumRange* magnitude_source[i])); break; } case OpacityChannel: { SetPixelOpacity(q,ClampToQuantum(QuantumRange* magnitude_source[i])); break; } case IndexChannel: { SetPixelIndex(indexes+x,ClampToQuantum(QuantumRange* magnitude_source[i])); break; } case GrayChannels: { SetPixelGray(q,ClampToQuantum(QuantumRange* magnitude_source[i])); break; } } i++; q++; } status=SyncCacheViewAuthenticPixels(magnitude_view,exception); if (status == MagickFalse) break; } i=0L; for (y=0L; y < (ssize_t) fourier_info->height; y++) { q=GetCacheViewAuthenticPixels(phase_view,0L,y,fourier_info->height,1UL, exception); if (q == (PixelPacket *) NULL) break; indexes=GetCacheViewAuthenticIndexQueue(phase_view); for (x=0L; x < (ssize_t) fourier_info->width; x++) { switch (fourier_info->channel) { case RedChannel: default: { SetPixelRed(q,ClampToQuantum(QuantumRange* phase_source[i])); break; } case GreenChannel: { SetPixelGreen(q,ClampToQuantum(QuantumRange* phase_source[i])); break; } case BlueChannel: { SetPixelBlue(q,ClampToQuantum(QuantumRange* phase_source[i])); break; } case OpacityChannel: { SetPixelOpacity(q,ClampToQuantum(QuantumRange* phase_source[i])); break; } case IndexChannel: { SetPixelIndex(indexes+x,ClampToQuantum(QuantumRange* phase_source[i])); break; } case GrayChannels: { SetPixelGray(q,ClampToQuantum(QuantumRange*phase_source[i])); break; } } i++; q++; } status=SyncCacheViewAuthenticPixels(phase_view,exception); if (status == MagickFalse) break; } phase_view=DestroyCacheView(phase_view); magnitude_view=DestroyCacheView(magnitude_view); phase_source=(double *) RelinquishMagickMemory(phase_source); magnitude_source=(double *) RelinquishMagickMemory(magnitude_source); return(status); }
static MagickBooleanType LoadTypeCache(SplayTreeInfo *type_cache, const char *xml,const char *filename,const size_t depth, ExceptionInfo *exception) { char font_path[MagickPathExtent], keyword[MagickPathExtent], *token; const char *q; MagickStatusType status; TypeInfo *type_info; /* Load the type map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading type configure file \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); status=MagickTrue; type_info=(TypeInfo *) NULL; token=AcquireString(xml); #if defined(MAGICKCORE_WINDOWS_SUPPORT) /* Determine the Ghostscript font path. */ *font_path='\0'; if (NTGhostscriptFonts(font_path,MagickPathExtent-2)) (void) ConcatenateMagickString(font_path,DirectorySeparator,MagickPathExtent); #endif for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetMagickToken(q,&q,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MagickPathExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MagickPathExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token); else { char path[MagickPathExtent], *xml; ExceptionInfo *sans_exception; *path='\0'; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MagickPathExtent); if (*token == *DirectorySeparator) (void) CopyMagickString(path,token,MagickPathExtent); else (void) ConcatenateMagickString(path,token,MagickPathExtent); sans_exception=AcquireExceptionInfo(); xml=FileToString(path,~0UL,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (xml != (char *) NULL) { status&=LoadTypeCache(type_cache,xml,path,depth+1, exception); xml=(char *) RelinquishMagickMemory(xml); } } } } continue; } if (LocaleCompare(keyword,"<type") == 0) { /* Type element. */ type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info)); if (type_info == (TypeInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(type_info,0,sizeof(*type_info)); type_info->path=ConstantString(filename); type_info->signature=MagickCoreSignature; continue; } if (type_info == (TypeInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=AddValueToSplayTree(type_cache,type_info->name,type_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name); type_info=(TypeInfo *) NULL; continue; } GetMagickToken(q,(const char **) NULL,token); if (*token != '=') continue; GetMagickToken(q,&q,token); GetMagickToken(q,&q,token); switch (*keyword) { case 'E': case 'e': { if (LocaleCompare((char *) keyword,"encoding") == 0) { type_info->encoding=ConstantString(token); break; } break; } case 'F': case 'f': { if (LocaleCompare((char *) keyword,"face") == 0) { type_info->face=StringToUnsignedLong(token); break; } if (LocaleCompare((char *) keyword,"family") == 0) { type_info->family=ConstantString(token); break; } if (LocaleCompare((char *) keyword,"format") == 0) { type_info->format=ConstantString(token); break; } if (LocaleCompare((char *) keyword,"foundry") == 0) { type_info->foundry=ConstantString(token); break; } if (LocaleCompare((char *) keyword,"fullname") == 0) { type_info->description=ConstantString(token); break; } break; } case 'G': case 'g': { if (LocaleCompare((char *) keyword,"glyphs") == 0) { if (SetTypeNodePath(filename,font_path,token,&type_info->glyphs) == MagickFalse) type_info=(TypeInfo *) DestroyTypeNode(type_info); break; } break; } case 'M': case 'm': { if (LocaleCompare((char *) keyword,"metrics") == 0) { if (SetTypeNodePath(filename,font_path,token,&type_info->metrics) == MagickFalse) type_info=(TypeInfo *) DestroyTypeNode(type_info); break; } break; } case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { type_info->name=ConstantString(token); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { type_info->stealth=IsStringTrue(token); break; } if (LocaleCompare((char *) keyword,"stretch") == 0) { type_info->stretch=(StretchType) ParseCommandOption( MagickStretchOptions,MagickFalse,token); break; } if (LocaleCompare((char *) keyword,"style") == 0) { type_info->style=(StyleType) ParseCommandOption(MagickStyleOptions, MagickFalse,token); break; } break; } case 'W': case 'w': { if (LocaleCompare((char *) keyword,"weight") == 0) { ssize_t weight; weight=ParseCommandOption(MagickWeightOptions,MagickFalse,token); if (weight == -1) weight=StringToUnsignedLong(token); type_info->weight=(size_t) weight; break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status != 0 ? MagickTrue : MagickFalse); }
static MagickBooleanType ForwardFourierTransform(FourierInfo *fourier_info, const Image *image,double *magnitude,double *phase,ExceptionInfo *exception) { CacheView *image_view; double n, *source; fftw_complex *fourier; fftw_plan fftw_r2c_plan; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t i, x; ssize_t y; /* Generate the forward Fourier transform. */ source=(double *) AcquireQuantumMemory((size_t) fourier_info->height, fourier_info->width*sizeof(*source)); if (source == (double *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); return(MagickFalse); } ResetMagickMemory(source,0,fourier_info->height*fourier_info->width* sizeof(*source)); i=0L; image_view=AcquireCacheView(image); for (y=0L; y < (ssize_t) fourier_info->height; y++) { p=GetCacheViewVirtualPixels(image_view,0L,y,fourier_info->width,1UL, exception); if (p == (const PixelPacket *) NULL) break; indexes=GetCacheViewVirtualIndexQueue(image_view); for (x=0L; x < (ssize_t) fourier_info->width; x++) { switch (fourier_info->channel) { case RedChannel: default: { source[i]=QuantumScale*GetPixelRed(p); break; } case GreenChannel: { source[i]=QuantumScale*GetPixelGreen(p); break; } case BlueChannel: { source[i]=QuantumScale*GetPixelBlue(p); break; } case OpacityChannel: { source[i]=QuantumScale*GetPixelOpacity(p); break; } case IndexChannel: { source[i]=QuantumScale*GetPixelIndex(indexes+x); break; } case GrayChannels: { source[i]=QuantumScale*GetPixelGray(p); break; } } i++; p++; } } image_view=DestroyCacheView(image_view); fourier=(fftw_complex *) AcquireQuantumMemory((size_t) fourier_info->height, fourier_info->center*sizeof(*fourier)); if (fourier == (fftw_complex *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); source=(double *) RelinquishMagickMemory(source); return(MagickFalse); } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp critical (MagickCore_ForwardFourierTransform) #endif fftw_r2c_plan=fftw_plan_dft_r2c_2d(fourier_info->width,fourier_info->width, source,fourier,FFTW_ESTIMATE); fftw_execute(fftw_r2c_plan); fftw_destroy_plan(fftw_r2c_plan); source=(double *) RelinquishMagickMemory(source); /* Normalize Fourier transform. */ n=(double) fourier_info->width*(double) fourier_info->width; i=0L; for (y=0L; y < (ssize_t) fourier_info->height; y++) for (x=0L; x < (ssize_t) fourier_info->center; x++) { #if defined(MAGICKCORE_HAVE_COMPLEX_H) fourier[i]/=n; #else fourier[i][0]/=n; fourier[i][1]/=n; #endif i++; } /* Generate magnitude and phase (or real and imaginary). */ i=0L; if (fourier_info->modulus != MagickFalse) for (y=0L; y < (ssize_t) fourier_info->height; y++) for (x=0L; x < (ssize_t) fourier_info->center; x++) { magnitude[i]=cabs(fourier[i]); phase[i]=carg(fourier[i]); i++; } else for (y=0L; y < (ssize_t) fourier_info->height; y++) for (x=0L; x < (ssize_t) fourier_info->center; x++) { magnitude[i]=creal(fourier[i]); phase[i]=cimag(fourier[i]); i++; } fourier=(fftw_complex *) RelinquishMagickMemory(fourier); return(MagickTrue); }
MagickExport MagickBooleanType LoadFontConfigFonts(SplayTreeInfo *type_cache, ExceptionInfo *exception) { #if !defined(FC_FULLNAME) #define FC_FULLNAME "fullname" #endif char extension[MagickPathExtent], name[MagickPathExtent]; FcChar8 *family, *file, *fullname, *style; FcConfig *font_config; FcFontSet *font_set; FcObjectSet *object_set; FcPattern *pattern; FcResult status; int slant, width, weight; register ssize_t i; TypeInfo *type_info; /* Load system fonts. */ (void) exception; font_config=FcInitLoadConfigAndFonts(); if (font_config == (FcConfig *) NULL) return(MagickFalse); font_set=(FcFontSet *) NULL; object_set=FcObjectSetBuild(FC_FULLNAME,FC_FAMILY,FC_STYLE,FC_SLANT, FC_WIDTH,FC_WEIGHT,FC_FILE,(char *) NULL); if (object_set != (FcObjectSet *) NULL) { pattern=FcPatternCreate(); if (pattern != (FcPattern *) NULL) { font_set=FcFontList(0,pattern,object_set); FcPatternDestroy(pattern); } FcObjectSetDestroy(object_set); } if (font_set == (FcFontSet *) NULL) { FcConfigDestroy(font_config); return(MagickFalse); } for (i=0; i < (ssize_t) font_set->nfont; i++) { status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family); if (status != FcResultMatch) continue; status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file); if (status != FcResultMatch) continue; *extension='\0'; GetPathComponent((const char *) file,ExtensionPath,extension); if ((*extension != '\0') && (LocaleCompare(extension,"gz") == 0)) continue; type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info)); if (type_info == (TypeInfo *) NULL) continue; (void) ResetMagickMemory(type_info,0,sizeof(*type_info)); type_info->path=ConstantString("System Fonts"); type_info->signature=MagickCoreSignature; (void) CopyMagickString(name,"Unknown",MagickPathExtent); status=FcPatternGetString(font_set->fonts[i],FC_FULLNAME,0,&fullname); if ((status == FcResultMatch) && (fullname != (FcChar8 *) NULL)) (void) CopyMagickString(name,(const char *) fullname,MagickPathExtent); else { if (family != (FcChar8 *) NULL) (void) CopyMagickString(name,(const char *) family,MagickPathExtent); status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style); if ((status == FcResultMatch) && (style != (FcChar8 *) NULL) && (LocaleCompare((const char *) style,"Regular") != 0)) { (void) ConcatenateMagickString(name," ",MagickPathExtent); (void) ConcatenateMagickString(name,(const char *) style, MagickPathExtent); } } type_info->name=ConstantString(name); (void) SubstituteString(&type_info->name," ","-"); type_info->family=ConstantString((const char *) family); status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant); type_info->style=NormalStyle; if (slant == FC_SLANT_ITALIC) type_info->style=ItalicStyle; if (slant == FC_SLANT_OBLIQUE) type_info->style=ObliqueStyle; status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width); type_info->stretch=NormalStretch; if (width >= FC_WIDTH_ULTRACONDENSED) type_info->stretch=UltraCondensedStretch; if (width >= FC_WIDTH_EXTRACONDENSED) type_info->stretch=ExtraCondensedStretch; if (width >= FC_WIDTH_CONDENSED) type_info->stretch=CondensedStretch; if (width >= FC_WIDTH_SEMICONDENSED) type_info->stretch=SemiCondensedStretch; if (width >= FC_WIDTH_NORMAL) type_info->stretch=NormalStretch; if (width >= FC_WIDTH_SEMIEXPANDED) type_info->stretch=SemiExpandedStretch; if (width >= FC_WIDTH_EXPANDED) type_info->stretch=ExpandedStretch; if (width >= FC_WIDTH_EXTRAEXPANDED) type_info->stretch=ExtraExpandedStretch; if (width >= FC_WIDTH_ULTRAEXPANDED) type_info->stretch=UltraExpandedStretch; type_info->weight=400; status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight); if (weight >= FC_WEIGHT_THIN) type_info->weight=100; if (weight >= FC_WEIGHT_EXTRALIGHT) type_info->weight=200; if (weight >= FC_WEIGHT_LIGHT) type_info->weight=300; if (weight >= FC_WEIGHT_NORMAL) type_info->weight=400; if (weight >= FC_WEIGHT_MEDIUM) type_info->weight=500; if (weight >= FC_WEIGHT_DEMIBOLD) type_info->weight=600; if (weight >= FC_WEIGHT_BOLD) type_info->weight=700; if (weight >= FC_WEIGHT_EXTRABOLD) type_info->weight=800; if (weight >= FC_WEIGHT_BLACK) type_info->weight=900; type_info->glyphs=ConstantString((const char *) file); (void) AddValueToSplayTree(type_cache,type_info->name,type_info); } FcFontSetDestroy(font_set); FcConfigDestroy(font_config); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + L o a d M i m e C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadMimeCache() loads the mime configurations which provides a mapping % between mime attributes and a mime name. % % The format of the LoadMimeCache method is: % % MagickBooleanType LoadMimeCache(LinkedListInfo *mime_cache, % const char *xml,const char *filename,const size_t depth, % ExceptionInfo *exception) % % A description of each parameter follows: % % o xml: The mime list in XML format. % % o filename: The mime list filename. % % o depth: depth of <include /> statements. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType LoadMimeCache(LinkedListInfo *mime_cache, const char *xml,const char *filename,const size_t depth, ExceptionInfo *exception) { const char *attribute; MimeInfo *mime_info = (MimeInfo *) NULL; MagickStatusType status; XMLTreeInfo *mime, *mime_map, *include; /* Load the mime map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading mime map \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); mime_map=NewXMLTree(xml,exception); if (mime_map == (XMLTreeInfo *) NULL) return(MagickFalse); status=MagickTrue; include=GetXMLTreeChild(mime_map,"include"); while (include != (XMLTreeInfo *) NULL) { /* Process include element. */ attribute=GetXMLTreeAttribute(include,"file"); if (attribute != (const char *) NULL) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",filename); else { char path[MagickPathExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MagickPathExtent); if (*attribute == *DirectorySeparator) (void) CopyMagickString(path,attribute,MagickPathExtent); else (void) ConcatenateMagickString(path,attribute,MagickPathExtent); xml=FileToXML(path,~0UL); if (xml != (char *) NULL) { status&=LoadMimeCache(mime_cache,xml,path,depth+1,exception); xml=DestroyString(xml); } } } include=GetNextXMLTreeTag(include); } mime=GetXMLTreeChild(mime_map,"mime"); while (mime != (XMLTreeInfo *) NULL) { const char *attribute; /* Process mime element. */ mime_info=(MimeInfo *) AcquireMagickMemory(sizeof(*mime_info)); if (mime_info == (MimeInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(mime_info,0,sizeof(*mime_info)); mime_info->path=ConstantString(filename); mime_info->signature=MagickCoreSignature; attribute=GetXMLTreeAttribute(mime,"data-type"); if (attribute != (const char *) NULL) mime_info->data_type=(DataType) ParseCommandOption(MagickDataTypeOptions, MagickTrue,attribute); attribute=GetXMLTreeAttribute(mime,"description"); if (attribute != (const char *) NULL) mime_info->description=ConstantString(attribute); attribute=GetXMLTreeAttribute(mime,"endian"); if (attribute != (const char *) NULL) mime_info->endian=(EndianType) ParseCommandOption(MagickEndianOptions, MagickTrue,attribute); attribute=GetXMLTreeAttribute(mime,"magic"); if (attribute != (const char *) NULL) { char *token; const char *p; register unsigned char *q; token=AcquireString(attribute); (void) SubstituteString((char **) &token,"<","<"); (void) SubstituteString((char **) &token,"&","&"); (void) SubstituteString((char **) &token,""","\""); mime_info->magic=(unsigned char *) AcquireString(token); q=mime_info->magic; for (p=token; *p != '\0'; ) { if (*p == '\\') { p++; if (isdigit((int) ((unsigned char) *p)) != 0) { char *end; *q++=(unsigned char) strtol(p,&end,8); p+=(end-p); mime_info->length++; continue; } switch (*p) { case 'b': *q='\b'; break; case 'f': *q='\f'; break; case 'n': *q='\n'; break; case 'r': *q='\r'; break; case 't': *q='\t'; break; case 'v': *q='\v'; break; case 'a': *q='a'; break; case '?': *q='\?'; break; default: *q=(unsigned char) (*p); break; } p++; q++; mime_info->length++; continue; } *q++=(unsigned char) (*p++); mime_info->length++; } token=DestroyString(token); if (mime_info->data_type != StringData) mime_info->value=(ssize_t) strtoul((char *) mime_info->magic, (char **) NULL,0); } attribute=GetXMLTreeAttribute(mime,"mask"); if (attribute != (const char *) NULL) mime_info->mask=(ssize_t) strtoul(attribute,(char **) NULL,0); attribute=GetXMLTreeAttribute(mime,"offset"); if (attribute != (const char *) NULL) { char *c; mime_info->offset=(MagickOffsetType) strtol(attribute,&c,0); if (*c == ':') mime_info->extent=(size_t) strtol(c+1,(char **) NULL,0); } attribute=GetXMLTreeAttribute(mime,"pattern"); if (attribute != (const char *) NULL) mime_info->pattern=ConstantString(attribute); attribute=GetXMLTreeAttribute(mime,"priority"); if (attribute != (const char *) NULL) mime_info->priority=(ssize_t) strtol(attribute,(char **) NULL,0); attribute=GetXMLTreeAttribute(mime,"stealth"); if (attribute != (const char *) NULL) mime_info->stealth=IsStringTrue(attribute); attribute=GetXMLTreeAttribute(mime,"type"); if (attribute != (const char *) NULL) mime_info->type=ConstantString(attribute); status=AppendValueToLinkedList(mime_cache,mime_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); mime=GetNextXMLTreeTag(mime); } mime_map=DestroyXMLTree(mime_map); return(status != 0 ? MagickTrue : MagickFalse); }
MagickExport Image *MontageImageList(const ImageInfo *image_info, const MontageInfo *montage_info,const Image *images,ExceptionInfo *exception) { #define MontageImageTag "Montage/Image" #define TileImageTag "Tile/Image" char tile_geometry[MagickPathExtent], *title; const char *value; DrawInfo *draw_info; FrameInfo frame_info; Image *image, **image_list, **master_list, *montage, *texture, *tile_image, *thumbnail; ImageInfo *clone_info; MagickBooleanType concatenate, proceed, status; MagickOffsetType tiles; MagickProgressMonitor progress_monitor; MagickStatusType flags; register ssize_t i; RectangleInfo bounds, geometry, extract_info; size_t bevel_width, border_width, extent, height, images_per_page, max_height, number_images, number_lines, sans, tiles_per_column, tiles_per_page, tiles_per_row, title_offset, total_tiles, width; ssize_t tile, x, x_offset, y, y_offset; TypeMetric metrics; /* Create image tiles. */ assert(images != (Image *) NULL); assert(images->signature == MagickCoreSignature); if (images->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename); assert(montage_info != (MontageInfo *) NULL); assert(montage_info->signature == MagickCoreSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); number_images=GetImageListLength(images); master_list=ImageListToArray(images,exception); image_list=master_list; image=image_list[0]; if (master_list == (Image **) NULL) ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); thumbnail=NewImageList(); for (i=0; i < (ssize_t) number_images; i++) { image=CloneImage(image_list[i],0,0,MagickTrue,exception); if (image == (Image *) NULL) break; (void) ParseAbsoluteGeometry("0x0+0+0",&image->page); progress_monitor=SetImageProgressMonitor(image,(MagickProgressMonitor) NULL, image->client_data); flags=ParseRegionGeometry(image,montage_info->geometry,&geometry,exception); thumbnail=ThumbnailImage(image,geometry.width,geometry.height,exception); if (thumbnail == (Image *) NULL) break; image_list[i]=thumbnail; (void) SetImageProgressMonitor(image,progress_monitor,image->client_data); proceed=SetImageProgress(image,TileImageTag,(MagickOffsetType) i, number_images); if (proceed == MagickFalse) break; image=DestroyImage(image); } if (i < (ssize_t) number_images) { if (thumbnail == (Image *) NULL) i--; for (tile=0; (ssize_t) tile <= i; tile++) if (image_list[tile] != (Image *) NULL) image_list[tile]=DestroyImage(image_list[tile]); master_list=(Image **) RelinquishMagickMemory(master_list); return((Image *) NULL); } /* Sort image list by increasing tile number. */ for (i=0; i < (ssize_t) number_images; i++) if (image_list[i]->scene == 0) break; if (i == (ssize_t) number_images) qsort((void *) image_list,(size_t) number_images,sizeof(*image_list), SceneCompare); /* Determine tiles per row and column. */ tiles_per_column=(size_t) sqrt((double) number_images); tiles_per_row=(size_t) ceil((double) number_images/tiles_per_column); x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &tiles_per_column,&tiles_per_row); /* Determine tile sizes. */ concatenate=MagickFalse; SetGeometry(image_list[0],&extract_info); extract_info.x=(ssize_t) montage_info->border_width; extract_info.y=(ssize_t) montage_info->border_width; if (montage_info->geometry != (char *) NULL) { /* Initialize tile geometry. */ flags=GetGeometry(montage_info->geometry,&extract_info.x,&extract_info.y, &extract_info.width,&extract_info.height); concatenate=((flags & RhoValue) == 0) && ((flags & SigmaValue) == 0) ? MagickTrue : MagickFalse; } border_width=montage_info->border_width; bevel_width=0; (void) ResetMagickMemory(&frame_info,0,sizeof(frame_info)); if (montage_info->frame != (char *) NULL) { char absolute_geometry[MagickPathExtent]; frame_info.width=extract_info.width; frame_info.height=extract_info.height; (void) FormatLocaleString(absolute_geometry,MagickPathExtent,"%s!", montage_info->frame); flags=ParseMetaGeometry(absolute_geometry,&frame_info.outer_bevel, &frame_info.inner_bevel,&frame_info.width,&frame_info.height); if ((flags & HeightValue) == 0) frame_info.height=frame_info.width; if ((flags & XiValue) == 0) frame_info.outer_bevel=(ssize_t) frame_info.width/2; if ((flags & PsiValue) == 0) frame_info.inner_bevel=frame_info.outer_bevel; frame_info.x=(ssize_t) frame_info.width; frame_info.y=(ssize_t) frame_info.height; bevel_width=(size_t) MagickMax(frame_info.inner_bevel, frame_info.outer_bevel); border_width=(size_t) MagickMax((ssize_t) frame_info.width, (ssize_t) frame_info.height); } for (i=0; i < (ssize_t) number_images; i++) { if (image_list[i]->columns > extract_info.width) extract_info.width=image_list[i]->columns; if (image_list[i]->rows > extract_info.height) extract_info.height=image_list[i]->rows; } /* Initialize draw attributes. */ clone_info=CloneImageInfo(image_info); clone_info->background_color=montage_info->background_color; clone_info->border_color=montage_info->border_color; draw_info=CloneDrawInfo(clone_info,(DrawInfo *) NULL); if (montage_info->font != (char *) NULL) (void) CloneString(&draw_info->font,montage_info->font); if (montage_info->pointsize != 0.0) draw_info->pointsize=montage_info->pointsize; draw_info->gravity=CenterGravity; draw_info->stroke=montage_info->stroke; draw_info->fill=montage_info->fill; draw_info->text=AcquireString(""); (void) GetTypeMetrics(image_list[0],draw_info,&metrics,exception); texture=NewImageList(); if (montage_info->texture != (char *) NULL) { (void) CopyMagickString(clone_info->filename,montage_info->texture, MagickPathExtent); texture=ReadImage(clone_info,exception); } /* Determine the number of lines in an next label. */ title=InterpretImageProperties(clone_info,image_list[0],montage_info->title, exception); title_offset=0; if (montage_info->title != (char *) NULL) title_offset=(size_t) (2*(metrics.ascent-metrics.descent)* MultilineCensus(title)+2*extract_info.y); number_lines=0; for (i=0; i < (ssize_t) number_images; i++) { value=GetImageProperty(image_list[i],"label",exception); if (value == (const char *) NULL) continue; if (MultilineCensus(value) > number_lines) number_lines=MultilineCensus(value); } /* Allocate next structure. */ tile_image=AcquireImage((ImageInfo *) NULL,exception); montage=AcquireImage(clone_info,exception); montage->background_color=montage_info->background_color; montage->scene=0; images_per_page=(number_images-1)/(tiles_per_row*tiles_per_column)+1; tiles=0; total_tiles=(size_t) number_images; for (i=0; i < (ssize_t) images_per_page; i++) { /* Determine bounding box. */ tiles_per_page=tiles_per_row*tiles_per_column; x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &sans,&sans); tiles_per_page=tiles_per_row*tiles_per_column; y_offset+=(ssize_t) title_offset; max_height=0; bounds.width=0; bounds.height=0; width=0; for (tile=0; tile < (ssize_t) tiles_per_page; tile++) { if (tile < (ssize_t) number_images) { width=concatenate != MagickFalse ? image_list[tile]->columns : extract_info.width; if (image_list[tile]->rows > max_height) max_height=image_list[tile]->rows; } x_offset+=(ssize_t) (width+2*(extract_info.x+border_width)); if (x_offset > (ssize_t) bounds.width) bounds.width=(size_t) x_offset; if (((tile+1) == (ssize_t) tiles_per_page) || (((tile+1) % tiles_per_row) == 0)) { x_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y, &sans,&sans); height=concatenate != MagickFalse ? max_height : extract_info.height; y_offset+=(ssize_t) (height+(extract_info.y+(ssize_t) border_width)*2+ (metrics.ascent-metrics.descent+4)*number_lines+ (montage_info->shadow != MagickFalse ? 4 : 0)); if (y_offset > (ssize_t) bounds.height) bounds.height=(size_t) y_offset; max_height=0; } } if (montage_info->shadow != MagickFalse) bounds.width+=4; /* Initialize montage image. */ (void) CopyMagickString(montage->filename,montage_info->filename, MagickPathExtent); montage->columns=(size_t) MagickMax((ssize_t) bounds.width,1); montage->rows=(size_t) MagickMax((ssize_t) bounds.height,1); (void) SetImageBackgroundColor(montage,exception); /* Set montage geometry. */ montage->montage=AcquireString((char *) NULL); tile=0; extent=1; while (tile < MagickMin((ssize_t) tiles_per_page,(ssize_t) number_images)) { extent+=strlen(image_list[tile]->filename)+1; tile++; } montage->directory=(char *) AcquireQuantumMemory(extent, sizeof(*montage->directory)); if ((montage->montage == (char *) NULL) || (montage->directory == (char *) NULL)) ThrowImageException(ResourceLimitError,"MemoryAllocationFailed"); x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &sans,&sans); y_offset+=(ssize_t) title_offset; (void) FormatLocaleString(montage->montage,MagickPathExtent, "%.20gx%.20g%+.20g%+.20g",(double) (extract_info.width+ (extract_info.x+border_width)*2),(double) (extract_info.height+ (extract_info.y+border_width)*2+(double) ((metrics.ascent- metrics.descent+4)*number_lines+(montage_info->shadow != MagickFalse ? 4 : 0))),(double) x_offset,(double) y_offset); *montage->directory='\0'; tile=0; while (tile < MagickMin((ssize_t) tiles_per_page,(ssize_t) number_images)) { (void) ConcatenateMagickString(montage->directory, image_list[tile]->filename,extent); (void) ConcatenateMagickString(montage->directory,"\n",extent); tile++; } progress_monitor=SetImageProgressMonitor(montage,(MagickProgressMonitor) NULL,montage->client_data); if (texture != (Image *) NULL) (void) TextureImage(montage,texture,exception); if (montage_info->title != (char *) NULL) { char geometry[MagickPathExtent]; DrawInfo *clone_info; TypeMetric metrics; /* Annotate composite image with title. */ clone_info=CloneDrawInfo(image_info,draw_info); clone_info->gravity=CenterGravity; clone_info->pointsize*=2.0; (void) GetTypeMetrics(image_list[0],clone_info,&metrics,exception); (void) FormatLocaleString(geometry,MagickPathExtent, "%.20gx%.20g%+.20g%+.20g",(double) montage->columns,(double) (metrics.ascent-metrics.descent),0.0,(double) extract_info.y+4); (void) CloneString(&clone_info->geometry,geometry); (void) CloneString(&clone_info->text,title); (void) AnnotateImage(montage,clone_info,exception); clone_info=DestroyDrawInfo(clone_info); } (void) SetImageProgressMonitor(montage,progress_monitor, montage->client_data); /* Copy tile to the composite. */ x_offset=0; y_offset=0; if (montage_info->tile != (char *) NULL) GetMontageGeometry(montage_info->tile,number_images,&x_offset,&y_offset, &sans,&sans); x_offset+=extract_info.x; y_offset+=(ssize_t) title_offset+extract_info.y; max_height=0; status=MagickTrue; for (tile=0; tile < MagickMin((ssize_t) tiles_per_page,(ssize_t) number_images); tile++) { /* Copy this tile to the composite. */ image=CloneImage(image_list[tile],0,0,MagickTrue,exception); progress_monitor=SetImageProgressMonitor(image, (MagickProgressMonitor) NULL,image->client_data); width=concatenate != MagickFalse ? image->columns : extract_info.width; if (image->rows > max_height) max_height=image->rows; height=concatenate != MagickFalse ? max_height : extract_info.height; if (border_width != 0) { Image *border_image; RectangleInfo border_info; /* Put a border around the image. */ border_info.width=border_width; border_info.height=border_width; if (montage_info->frame != (char *) NULL) { border_info.width=(width-image->columns+1)/2; border_info.height=(height-image->rows+1)/2; } border_image=BorderImage(image,&border_info,image->compose,exception); if (border_image != (Image *) NULL) { image=DestroyImage(image); image=border_image; } if ((montage_info->frame != (char *) NULL) && (image->compose == DstOutCompositeOp)) { (void) SetPixelChannelMask(image,AlphaChannel); (void) NegateImage(image,MagickFalse,exception); (void) SetPixelChannelMask(image,DefaultChannels); } } /* Gravitate as specified by the tile gravity. */ tile_image->columns=width; tile_image->rows=height; tile_image->gravity=montage_info->gravity; if (image->gravity != UndefinedGravity) tile_image->gravity=image->gravity; (void) FormatLocaleString(tile_geometry,MagickPathExtent,"%.20gx%.20g+0+0", (double) image->columns,(double) image->rows); flags=ParseGravityGeometry(tile_image,tile_geometry,&geometry,exception); x=(ssize_t) (geometry.x+border_width); y=(ssize_t) (geometry.y+border_width); if ((montage_info->frame != (char *) NULL) && (bevel_width != 0)) { FrameInfo extract_info; Image *frame_image; /* Put an ornamental border around this tile. */ extract_info=frame_info; extract_info.width=width+2*frame_info.width; extract_info.height=height+2*frame_info.height; value=GetImageProperty(image,"label",exception); if (value != (const char *) NULL) extract_info.height+=(size_t) ((metrics.ascent-metrics.descent+4)* MultilineCensus(value)); frame_image=FrameImage(image,&extract_info,image->compose,exception); if (frame_image != (Image *) NULL) { image=DestroyImage(image); image=frame_image; } x=0; y=0; } if (LocaleCompare(image->magick,"NULL") != 0) { /* Composite background with tile. */ if (montage_info->shadow != MagickFalse) { Image *shadow_image; /* Shadow image. */ (void) QueryColorCompliance("#0000",AllCompliance, &image->background_color,exception); shadow_image=ShadowImage(image,80.0,2.0,5,5,exception); if (shadow_image != (Image *) NULL) { (void) CompositeImage(shadow_image,image,OverCompositeOp, MagickTrue,0,0,exception); image=DestroyImage(image); image=shadow_image; } } (void) CompositeImage(montage,image,image->compose,MagickTrue, x_offset+x,y_offset+y,exception); value=GetImageProperty(image,"label",exception); if (value != (const char *) NULL) { char geometry[MagickPathExtent]; /* Annotate composite tile with label. */ (void) FormatLocaleString(geometry,MagickPathExtent, "%.20gx%.20g%+.20g%+.20g",(double) ((montage_info->frame ? image->columns : width)-2*border_width),(double) (metrics.ascent-metrics.descent+4)*MultilineCensus(value), (double) (x_offset+border_width),(double) ((montage_info->frame ? y_offset+height+border_width+4 : y_offset+extract_info.height+border_width+ (montage_info->shadow != MagickFalse ? 4 : 0))+bevel_width)); (void) CloneString(&draw_info->geometry,geometry); (void) CloneString(&draw_info->text,value); (void) AnnotateImage(montage,draw_info,exception); } } x_offset+=(ssize_t) (width+2*(extract_info.x+border_width)); if (((tile+1) == (ssize_t) tiles_per_page) || (((tile+1) % tiles_per_row) == 0)) { x_offset=extract_info.x; y_offset+=(ssize_t) (height+(extract_info.y+border_width)*2+ (metrics.ascent-metrics.descent+4)*number_lines+ (montage_info->shadow != MagickFalse ? 4 : 0)); max_height=0; } if (images->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; proceed=SetImageProgress(image,MontageImageTag,tiles,total_tiles); if (proceed == MagickFalse) status=MagickFalse; } image_list[tile]=DestroyImage(image_list[tile]); image=DestroyImage(image); tiles++; } (void) status; if ((i+1) < (ssize_t) images_per_page) { /* Allocate next image structure. */ AcquireNextImage(clone_info,montage,exception); if (GetNextImageInList(montage) == (Image *) NULL) { montage=DestroyImageList(montage); return((Image *) NULL); } montage=GetNextImageInList(montage); montage->background_color=montage_info->background_color; image_list+=tiles_per_page; number_images-=tiles_per_page; } } tile_image=DestroyImage(tile_image); if (texture != (Image *) NULL) texture=DestroyImage(texture); title=DestroyString(title); master_list=(Image **) RelinquishMagickMemory(master_list); draw_info=DestroyDrawInfo(draw_info); clone_info=DestroyImageInfo(clone_info); return(GetFirstImageInList(montage)); }
static MagickBooleanType WriteCALSImage(const ImageInfo *image_info, Image *image) { char header[129]; Image *group4_image; ImageInfo *write_info; MagickBooleanType status; register ssize_t i; size_t density, length, orient_x, orient_y; ssize_t count; unsigned char *group4; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); /* Create standard CALS header. */ count=WriteCALSRecord(image,"srcdocid: NONE"); (void) count; count=WriteCALSRecord(image,"dstdocid: NONE"); count=WriteCALSRecord(image,"txtfilid: NONE"); count=WriteCALSRecord(image,"figid: NONE"); count=WriteCALSRecord(image,"srcgph: NONE"); count=WriteCALSRecord(image,"docls: NONE"); count=WriteCALSRecord(image,"rtype: 1"); orient_x=0; orient_y=0; switch (image->orientation) { case TopRightOrientation: { orient_x=180; orient_y=270; break; } case BottomRightOrientation: { orient_x=180; orient_y=90; break; } case BottomLeftOrientation: { orient_y=90; break; } case LeftTopOrientation: { orient_x=270; break; } case RightTopOrientation: { orient_x=270; orient_y=180; break; } case RightBottomOrientation: { orient_x=90; orient_y=180; break; } case LeftBottomOrientation: { orient_x=90; break; } default: { orient_y=270; } } (void) FormatLocaleString(header,MaxTextExtent,"rorient: %03ld,%03ld", (long) orient_x,(long) orient_y); count=WriteCALSRecord(image,header); (void) FormatLocaleString(header,MaxTextExtent,"rpelcnt: %06lu,%06lu", (unsigned long) image->columns,(unsigned long) image->rows); count=WriteCALSRecord(image,header); density=200; if (image_info->density != (char *) NULL) { GeometryInfo geometry_info; (void) ParseGeometry(image_info->density,&geometry_info); density=(size_t) floor(geometry_info.rho+0.5); } (void) FormatLocaleString(header,MaxTextExtent,"rdensty: %04lu", (unsigned long) density); count=WriteCALSRecord(image,header); count=WriteCALSRecord(image,"notes: NONE"); (void) ResetMagickMemory(header,' ',128); for (i=0; i < 5; i++) (void) WriteBlob(image,128,(unsigned char *) header); /* Write CALS pixels. */ write_info=CloneImageInfo(image_info); (void) CopyMagickString(write_info->filename,"GROUP4:",MaxTextExtent); (void) CopyMagickString(write_info->magick,"GROUP4",MaxTextExtent); group4_image=CloneImage(image,0,0,MagickTrue,&image->exception); if (group4_image == (Image *) NULL) { (void) CloseBlob(image); return(MagickFalse); } group4=(unsigned char *) ImageToBlob(write_info,group4_image,&length, &image->exception); group4_image=DestroyImage(group4_image); if (group4 == (unsigned char *) NULL) { (void) CloseBlob(image); return(MagickFalse); } write_info=DestroyImageInfo(write_info); if (WriteBlob(image,length,group4) != (ssize_t) length) status=MagickFalse; group4=(unsigned char *) RelinquishMagickMemory(group4); (void) CloseBlob(image); return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d S C R E E N S H O T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadSCREENSHOTImage() Takes a screenshot from the monitor(s). % % The format of the ReadSCREENSHOTImage method is: % % Image *ReadXImage(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 *ReadSCREENSHOTImage(const ImageInfo *image_info, ExceptionInfo *exception) { Image *image; 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=(Image *) NULL; #if defined(MAGICKCORE_WINGDI32_DELEGATE) { BITMAPINFO bmi; DISPLAY_DEVICE device; HBITMAP bitmap, bitmapOld; HDC bitmapDC, hDC; Image *screen; int i; MagickBooleanType status; register PixelPacket *q; register ssize_t x; RGBTRIPLE *p; ssize_t y; assert(image_info != (const ImageInfo *) NULL); i=0; device.cb = sizeof(device); image=(Image *) NULL; while(EnumDisplayDevices(NULL,i,&device,0) && ++i) { if ((device.StateFlags & DISPLAY_DEVICE_ACTIVE) != DISPLAY_DEVICE_ACTIVE) continue; hDC=CreateDC(device.DeviceName,device.DeviceName,NULL,NULL); if (hDC == (HDC) NULL) ThrowReaderException(CoderError,"UnableToCreateDC"); screen=AcquireImage(image_info); screen->columns=(size_t) GetDeviceCaps(hDC,HORZRES); screen->rows=(size_t) GetDeviceCaps(hDC,VERTRES); screen->storage_class=DirectClass; status=SetImageExtent(screen,screen->columns,screen->rows); if (status == MagickFalse) { InheritException(exception,&image->exception); return(DestroyImageList(image)); } if (image == (Image *) NULL) image=screen; else AppendImageToList(&image,screen); bitmapDC=CreateCompatibleDC(hDC); if (bitmapDC == (HDC) NULL) { DeleteDC(hDC); ThrowReaderException(CoderError,"UnableToCreateDC"); } (void) ResetMagickMemory(&bmi,0,sizeof(BITMAPINFO)); bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth=(LONG) screen->columns; bmi.bmiHeader.biHeight=(-1)*(LONG) screen->rows; bmi.bmiHeader.biPlanes=1; bmi.bmiHeader.biBitCount=24; bmi.bmiHeader.biCompression=BI_RGB; bitmap=CreateDIBSection(hDC,&bmi,DIB_RGB_COLORS,(void **) &p,NULL,0); if (bitmap == (HBITMAP) NULL) { DeleteDC(hDC); DeleteDC(bitmapDC); ThrowReaderException(CoderError,"UnableToCreateBitmap"); } bitmapOld=(HBITMAP) SelectObject(bitmapDC,bitmap); if (bitmapOld == (HBITMAP) NULL) { DeleteDC(hDC); DeleteDC(bitmapDC); DeleteObject(bitmap); ThrowReaderException(CoderError,"UnableToCreateBitmap"); } BitBlt(bitmapDC,0,0,(int) screen->columns,(int) screen->rows,hDC,0,0, SRCCOPY); (void) SelectObject(bitmapDC,bitmapOld); for (y=0; y < (ssize_t) screen->rows; y++) { q=QueueAuthenticPixels(screen,0,y,screen->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) screen->columns; x++) { SetPixelRed(q,ScaleCharToQuantum(p->rgbtRed)); SetPixelGreen(q,ScaleCharToQuantum(p->rgbtGreen)); SetPixelBlue(q,ScaleCharToQuantum(p->rgbtBlue)); SetPixelOpacity(q,OpaqueOpacity); p++; q++; } if (SyncAuthenticPixels(screen,exception) == MagickFalse) break; } DeleteDC(hDC); DeleteDC(bitmapDC); DeleteObject(bitmap); } } #elif defined(MAGICKCORE_X11_DELEGATE) { const char *option; XImportInfo ximage_info; (void) exception; XGetImportInfo(&ximage_info); option=GetImageOption(image_info,"x:screen"); if (option != (const char *) NULL) ximage_info.screen=IsMagickTrue(option); option=GetImageOption(image_info,"x:silent"); if (option != (const char *) NULL) ximage_info.silent=IsMagickTrue(option); image=XImportImage(image_info,&ximage_info); } #endif return(image); }
static MagickBooleanType LoadCoderList(const char *xml,const char *filename, const size_t depth,ExceptionInfo *exception) { char keyword[MaxTextExtent], *token; const char *q; CoderInfo *coder_info; MagickBooleanType status; /* Load the coder map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading coder configuration file \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (coder_list == (SplayTreeInfo *) NULL) { coder_list=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, DestroyCoderNode); if (coder_list == (SplayTreeInfo *) NULL) { ThrowFileException(exception,ResourceLimitError, "MemoryAllocationFailed",filename); return(MagickFalse); } } status=MagickTrue; coder_info=(CoderInfo *) NULL; token=AcquireString(xml); for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetMagickToken(q,&q,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MaxTextExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token); else { char path[MaxTextExtent], *xml; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); if (*token == *DirectorySeparator) (void) CopyMagickString(path,token,MaxTextExtent); else (void) ConcatenateMagickString(path,token,MaxTextExtent); xml=FileToString(path,~0,exception); if (xml != (char *) NULL) { status=LoadCoderList(xml,path,depth+1,exception); xml=(char *) RelinquishMagickMemory(xml); } } } } continue; } if (LocaleCompare(keyword,"<coder") == 0) { /* Coder element. */ coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info)); if (coder_info == (CoderInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info)); coder_info->path=ConstantString(filename); coder_info->exempt=MagickFalse; coder_info->signature=MagickSignature; continue; } if (coder_info == (CoderInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=AddValueToSplayTree(coder_list,ConstantString( coder_info->magick),coder_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", coder_info->magick); coder_info=(CoderInfo *) NULL; } GetMagickToken(q,(const char **) NULL,token); if (*token != '=') continue; GetMagickToken(q,&q,token); GetMagickToken(q,&q,token); switch (*keyword) { case 'M': case 'm': { if (LocaleCompare((char *) keyword,"magick") == 0) { coder_info->magick=ConstantString(token); break; } break; } case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { coder_info->name=ConstantString(token); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { coder_info->stealth=IsMagickTrue(token); break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status); }
static MagickBooleanType DecodeImage(Image *image, const MagickBooleanType compression,unsigned char *pixels) { #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__MINGW32__) #define BI_RGB 0 #define BI_RLE8 1 #define BI_RLE4 2 #define BI_BITFIELDS 3 #endif int count; ssize_t y; register ssize_t i, x; register unsigned char *p, *q; unsigned char byte; assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(pixels != (unsigned char *) NULL); (void) ResetMagickMemory(pixels,0,(size_t) image->columns*image->rows* sizeof(*pixels)); byte=0; x=0; p=pixels; q=pixels+(size_t) image->columns*image->rows; for (y=0; y < (ssize_t) image->rows; ) { if ((p < pixels) || (p >= q)) break; count=ReadBlobByte(image); if (count == EOF) break; if (count != 0) { count=(int) MagickMin((size_t) count,(size_t) (q-p)); /* Encoded mode. */ byte=(unsigned char) ReadBlobByte(image); if (compression == BI_RLE8) { for (i=0; i < count; i++) *p++=(unsigned char) byte; } else { for (i=0; i < count; i++) *p++=(unsigned char) ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f)); } x+=count; } else {
static Image *ReadFITSImage(const ImageInfo *image_info, ExceptionInfo *exception) { typedef struct _FITSInfo { MagickBooleanType extend, simple; int bits_per_pixel, columns, rows, number_axes, number_planes; double min_data, max_data, zero, scale; EndianType endian; } FITSInfo; char *comment, keyword[9], property[MaxTextExtent], value[73]; double pixel, scale; FITSInfo fits_info; Image *image; int c; ssize_t scene, y; MagickBooleanType status; MagickSizeType number_pixels; register ssize_t i, x; register PixelPacket *q; ssize_t count; /* 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); } /* Initialize image header. */ (void) ResetMagickMemory(&fits_info,0,sizeof(fits_info)); fits_info.extend=MagickFalse; fits_info.simple=MagickFalse; fits_info.bits_per_pixel=8; fits_info.columns=1; fits_info.rows=1; fits_info.rows=1; fits_info.number_planes=1; fits_info.min_data=0.0; fits_info.max_data=0.0; fits_info.zero=0.0; fits_info.scale=1.0; fits_info.endian=MSBEndian; /* Decode image header. */ for (comment=(char *) NULL; EOFBlob(image) == MagickFalse; ) { for ( ; EOFBlob(image) == MagickFalse; ) { register char *p; count=ReadBlob(image,8,(unsigned char *) keyword); if (count != 8) break; for (i=0; i < 8; i++) { if (isspace((int) ((unsigned char) keyword[i])) != 0) break; keyword[i]=tolower((int) ((unsigned char) keyword[i])); } keyword[i]='\0'; count=ReadBlob(image,72,(unsigned char *) value); if (count != 72) break; value[72]='\0'; p=value; if (*p == '=') { p+=2; while (isspace((int) ((unsigned char) *p)) != 0) p++; } if (LocaleCompare(keyword,"end") == 0) break; if (LocaleCompare(keyword,"extend") == 0) fits_info.extend=(*p == 'T') || (*p == 't') ? MagickTrue : MagickFalse; if (LocaleCompare(keyword,"simple") == 0) fits_info.simple=(*p == 'T') || (*p == 't') ? MagickTrue : MagickFalse; if (LocaleCompare(keyword,"bitpix") == 0) fits_info.bits_per_pixel=StringToLong(p); if (LocaleCompare(keyword,"naxis") == 0) fits_info.number_axes=StringToLong(p); if (LocaleCompare(keyword,"naxis1") == 0) fits_info.columns=StringToLong(p); if (LocaleCompare(keyword,"naxis2") == 0) fits_info.rows=StringToLong(p); if (LocaleCompare(keyword,"naxis3") == 0) fits_info.number_planes=StringToLong(p); if (LocaleCompare(keyword,"datamax") == 0) fits_info.max_data=StringToDouble(p); if (LocaleCompare(keyword,"datamin") == 0) fits_info.min_data=StringToDouble(p); if (LocaleCompare(keyword,"bzero") == 0) fits_info.zero=StringToDouble(p); if (LocaleCompare(keyword,"bscale") == 0) fits_info.scale=StringToDouble(p); if (LocaleCompare(keyword,"comment") == 0) { if (comment == (char *) NULL) comment=ConstantString(p); else (void) ConcatenateString(&comment,p); } if (LocaleCompare(keyword,"xendian") == 0) { if (LocaleNCompare(p,"big",3) == 0) fits_info.endian=MSBEndian; else fits_info.endian=LSBEndian; } (void) FormatMagickString(property,MaxTextExtent,"fits:%s",keyword); (void) SetImageProperty(image,property,p); } c=0; while (((TellBlob(image) % FITSBlocksize) != 0) && (c != EOF)) c=ReadBlobByte(image); if (fits_info.extend == MagickFalse) break; number_pixels=(MagickSizeType) fits_info.columns*fits_info.rows; if ((fits_info.simple != MagickFalse) && (fits_info.number_axes >= 1) && (fits_info.number_axes <= 4) && (number_pixels != 0)) break; } /* Verify that required image information is defined. */ if (comment != (char *) NULL) { (void) SetImageProperty(image,"comment",comment); comment=DestroyString(comment); } if (EOFBlob(image) != MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); number_pixels=(MagickSizeType) fits_info.columns*fits_info.rows; if ((fits_info.simple == MagickFalse) || (fits_info.number_axes < 1) || (fits_info.number_axes > 4) || (number_pixels == 0)) ThrowReaderException(CorruptImageError,"ImageTypeNotSupported"); for (scene=0; scene < (ssize_t) fits_info.number_planes; scene++) { image->columns=(size_t) fits_info.columns; image->rows=(size_t) fits_info.rows; image->depth=(size_t) (fits_info.bits_per_pixel < 0 ? -1 : 1)* fits_info.bits_per_pixel; image->endian=fits_info.endian; image->scene=(size_t) scene; if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; /* Initialize image structure. */ if ((fits_info.min_data != 0.0) || (fits_info.max_data != 0.0)) { if ((fits_info.bits_per_pixel != 0) && (fits_info.max_data == 0.0)) fits_info.max_data=GetFITSPixelRange((size_t) fits_info.bits_per_pixel); } else GetFITSPixelExtrema(image,fits_info.bits_per_pixel,&fits_info.min_data, &fits_info.max_data); /* Convert FITS pixels to pixel packets. */ scale=(double) QuantumRange/(fits_info.scale*(fits_info.max_data- fits_info.min_data)+fits_info.zero); for (y=(ssize_t) image->rows-1; y >= 0; y--) { q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { pixel=GetFITSPixel(image,fits_info.bits_per_pixel); q->red=(Quantum) ClampToQuantum(scale*(fits_info.scale*(pixel- fits_info.min_data)+fits_info.zero)); q->green=q->red; q->blue=q->red; 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 (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 (scene < (ssize_t) (fits_info.number_planes-1)) { /* 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; } } (void) CloseBlob(image); return(GetFirstImageInList(image)); }
static MagickBooleanType LoadLocaleList(const char *xml,const char *filename, const char *locale,const size_t depth,ExceptionInfo *exception) { char keyword[MaxTextExtent], message[MaxTextExtent], tag[MaxTextExtent], *token; const char *q; FatalErrorHandler fatal_handler; LocaleInfo *locale_info; MagickBooleanType status; register char *p; /* Read the locale configure file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading locale configure file \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (locale_list == (SplayTreeInfo *) NULL) { locale_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL, DestroyLocaleNode); if (locale_list == (SplayTreeInfo *) NULL) return(MagickFalse); } status=MagickTrue; locale_info=(LocaleInfo *) NULL; *tag='\0'; *message='\0'; *keyword='\0'; fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler); token=AcquireString(xml); for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetMagickToken(q,&q,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MaxTextExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) { GetMagickToken(q,&q,token); while (isspace((int) ((unsigned char) *q)) != 0) q++; } continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) { GetMagickToken(q,&q,token); while (isspace((int) ((unsigned char) *q)) != 0) q++; } continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"locale") == 0) { if (LocaleCompare(locale,token) != 0) break; continue; } if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token); else { char path[MaxTextExtent], *xml; *path='\0'; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); if (*token == *DirectorySeparator) (void) CopyMagickString(path,token,MaxTextExtent); else (void) ConcatenateMagickString(path,token,MaxTextExtent); xml=FileToString(path,~0,exception); if (xml != (char *) NULL) { status=LoadLocaleList(xml,path,locale,depth+1,exception); xml=(char *) RelinquishMagickMemory(xml); } } } } continue; } if (LocaleCompare(keyword,"<locale") == 0) { /* Locale element. */ while ((*token != '>') && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); } continue; } if (LocaleCompare(keyword,"</locale>") == 0) { ChopLocaleComponents(tag,1); (void) ConcatenateMagickString(tag,"/",MaxTextExtent); continue; } if (LocaleCompare(keyword,"<localemap>") == 0) continue; if (LocaleCompare(keyword,"</localemap>") == 0) continue; if (LocaleCompare(keyword,"<message") == 0) { /* Message element. */ while ((*token != '>') && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"name") == 0) { (void) ConcatenateMagickString(tag,token,MaxTextExtent); (void) ConcatenateMagickString(tag,"/",MaxTextExtent); } } for (p=(char *) q; (*q != '<') && (*q != '\0'); q++) ; while (isspace((int) ((unsigned char) *p)) != 0) p++; q--; while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p)) q--; (void) CopyMagickString(message,p,(size_t) (q-p+2)); locale_info=(LocaleInfo *) AcquireMagickMemory(sizeof(*locale_info)); if (locale_info == (LocaleInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(locale_info,0,sizeof(*locale_info)); locale_info->path=ConstantString(filename); locale_info->tag=ConstantString(tag); locale_info->message=ConstantString(message); locale_info->signature=MagickSignature; status=AddValueToSplayTree(locale_list,locale_info->tag,locale_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", locale_info->tag); (void) ConcatenateMagickString(tag,message,MaxTextExtent); (void) ConcatenateMagickString(tag,"\n",MaxTextExtent); q++; continue; } if (LocaleCompare(keyword,"</message>") == 0) { ChopLocaleComponents(tag,2); (void) ConcatenateMagickString(tag,"/",MaxTextExtent); continue; } if (*keyword == '<') { /* Subpath element. */ if (*(keyword+1) == '?') continue; if (*(keyword+1) == '/') { ChopLocaleComponents(tag,1); if (*tag != '\0') (void) ConcatenateMagickString(tag,"/",MaxTextExtent); continue; } token[strlen(token)-1]='\0'; (void) CopyMagickString(token,token+1,MaxTextExtent); (void) ConcatenateMagickString(tag,token,MaxTextExtent); (void) ConcatenateMagickString(tag,"/",MaxTextExtent); continue; } GetMagickToken(q,(const char **) NULL,token); if (*token != '=') continue; } token=(char *) RelinquishMagickMemory(token); (void) SetFatalErrorHandler(fatal_handler); return(status); }
static Image *ReadEMFImage(const ImageInfo *image_info, ExceptionInfo *exception) { BITMAPINFO DIBinfo; HBITMAP hBitmap, hOldBitmap; HDC hDC; HENHMETAFILE hemf; Image *image; RECT rect; register ssize_t x; register PixelPacket *q; RGBQUAD *pBits, *ppBits; ssize_t height, width, y; image=AcquireImage(image_info); hemf=ReadEnhMetaFile(image_info->filename,&width,&height); if (hemf == (HENHMETAFILE) NULL) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if ((image->columns == 0) || (image->rows == 0)) { double y_resolution, x_resolution; y_resolution=DefaultResolution; x_resolution=DefaultResolution; if (image->y_resolution > 0) { y_resolution=image->y_resolution; if (image->units == PixelsPerCentimeterResolution) y_resolution*=CENTIMETERS_INCH; } if (image->x_resolution > 0) { x_resolution=image->x_resolution; if (image->units == PixelsPerCentimeterResolution) x_resolution*=CENTIMETERS_INCH; } image->rows=(size_t) ((height/1000.0/CENTIMETERS_INCH)*y_resolution+0.5); image->columns=(size_t) ((width/1000.0/CENTIMETERS_INCH)* x_resolution+0.5); } if (image_info->size != (char *) NULL) { ssize_t x; image->columns=width; image->rows=height; x=0; y=0; (void) GetGeometry(image_info->size,&x,&y,&image->columns,&image->rows); } if (image_info->page != (char *) NULL) { char *geometry; register char *p; MagickStatusType flags; ssize_t sans; geometry=GetPageGeometry(image_info->page); p=strchr(geometry,'>'); if (p == (char *) NULL) { flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns, &image->rows); if (image->x_resolution != 0.0) image->columns=(size_t) floor((image->columns*image->x_resolution)+ 0.5); if (image->y_resolution != 0.0) image->rows=(size_t) floor((image->rows*image->y_resolution)+0.5); } else { *p='\0'; flags=ParseMetaGeometry(geometry,&sans,&sans,&image->columns, &image->rows); if (image->x_resolution != 0.0) image->columns=(size_t) floor(((image->columns*image->x_resolution)/ DefaultResolution)+0.5); if (image->y_resolution != 0.0) image->rows=(size_t) floor(((image->rows*image->y_resolution)/ DefaultResolution)+0.5); } (void) flags; geometry=DestroyString(geometry); } hDC=GetDC(NULL); if (hDC == (HDC) NULL) { DeleteEnhMetaFile(hemf); ThrowReaderException(ResourceLimitError,"UnableToCreateADC"); } /* Initialize the bitmap header info. */ (void) ResetMagickMemory(&DIBinfo,0,sizeof(BITMAPINFO)); DIBinfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); DIBinfo.bmiHeader.biWidth=(LONG) image->columns; DIBinfo.bmiHeader.biHeight=(-1)*(LONG) image->rows; DIBinfo.bmiHeader.biPlanes=1; DIBinfo.bmiHeader.biBitCount=32; DIBinfo.bmiHeader.biCompression=BI_RGB; hBitmap=CreateDIBSection(hDC,&DIBinfo,DIB_RGB_COLORS,(void **) &ppBits,NULL, 0); ReleaseDC(NULL,hDC); if (hBitmap == (HBITMAP) NULL) { DeleteEnhMetaFile(hemf); ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap"); } hDC=CreateCompatibleDC(NULL); if (hDC == (HDC) NULL) { DeleteEnhMetaFile(hemf); DeleteObject(hBitmap); ThrowReaderException(ResourceLimitError,"UnableToCreateADC"); } hOldBitmap=(HBITMAP) SelectObject(hDC,hBitmap); if (hOldBitmap == (HBITMAP) NULL) { DeleteEnhMetaFile(hemf); DeleteDC(hDC); DeleteObject(hBitmap); ThrowReaderException(ResourceLimitError,"UnableToCreateBitmap"); } /* Initialize the bitmap to the image background color. */ pBits=ppBits; for (y=0; y < (ssize_t) image->rows; y++) { for (x=0; x < (ssize_t) image->columns; x++) { pBits->rgbRed=ScaleQuantumToChar(image->background_color.red); pBits->rgbGreen=ScaleQuantumToChar(image->background_color.green); pBits->rgbBlue=ScaleQuantumToChar(image->background_color.blue); pBits++; } } rect.top=0; rect.left=0; rect.right=(LONG) image->columns; rect.bottom=(LONG) image->rows; /* Convert metafile pixels. */ PlayEnhMetaFile(hDC,hemf,&rect); pBits=ppBits; for (y=0; y < (ssize_t) image->rows; y++) { 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(pBits->rgbRed)); SetPixelGreen(q,ScaleCharToQuantum(pBits->rgbGreen)); SetPixelBlue(q,ScaleCharToQuantum(pBits->rgbBlue)); SetPixelOpacity(q,OpaqueOpacity); pBits++; q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; } DeleteEnhMetaFile(hemf); SelectObject(hDC,hOldBitmap); DeleteDC(hDC); DeleteObject(hBitmap); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % A c q u i r e C o n f i g u r e C a c h e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AcquireConfigureCache() caches one or more configure configurations which % provides a mapping between configure attributes and a configure name. % % The format of the AcquireConfigureCache method is: % % LinkedListInfo *AcquireConfigureCache(const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: the font file name. % % o exception: return any errors or warnings in this structure. % */ static LinkedListInfo *AcquireConfigureCache(const char *filename, ExceptionInfo *exception) { const StringInfo *option; LinkedListInfo *configure_cache, *options; MagickStatusType status; register ssize_t i; /* Load external configure map. */ configure_cache=NewLinkedList(0); if (configure_cache == (LinkedListInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); status=MagickTrue; options=GetConfigureOptions(filename,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); while (option != (const StringInfo *) NULL) { status&=LoadConfigureCache(configure_cache,(const char *) GetStringInfoDatum(option),GetStringInfoPath(option),0,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); } options=DestroyConfigureOptions(options); /* Load built-in configure map. */ for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++) { ConfigureInfo *configure_info; register const ConfigureMapInfo *p; p=ConfigureMap+i; configure_info=(ConfigureInfo *) AcquireMagickMemory( sizeof(*configure_info)); if (configure_info == (ConfigureInfo *) NULL) { (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name); continue; } (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info)); configure_info->path=(char *) "[built-in]"; configure_info->name=(char *) p->name; configure_info->value=(char *) p->value; configure_info->exempt=MagickTrue; configure_info->signature=MagickSignature; status&=AppendValueToLinkedList(configure_cache,configure_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'", configure_info->name); } return(configure_cache); }
static MagickBooleanType ReadOneLayer(Image* image,XCFDocInfo* inDocInfo, XCFLayerInfo *outLayer ) { long i; MagickOffsetType offset; unsigned int foundPropEnd = 0; unsigned long 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); unsigned long 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 = (long) ReadBlobMSBLong(image); outLayer->offset_y = (long) 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 < (long) prop_size; i++ ) (void) ReadBlobByte(image); /* long 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 -= (unsigned long) 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 WritePCLImage(const ImageInfo *image_info,Image *image) { char buffer[MaxTextExtent]; const char *option; MagickBooleanType status; MagickOffsetType scene; register const IndexPacket *indexes; register const PixelPacket *p; register ssize_t i, x; register unsigned char *q; size_t density, length, one, packets; ssize_t y; unsigned char bits_per_pixel, *compress_pixels, *pixels, *previous_pixels; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); density=75; if (image_info->density != (char *) NULL) { GeometryInfo geometry; (void) ParseGeometry(image_info->density,&geometry); density=(size_t) geometry.rho; } scene=0; one=1; do { if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,sRGBColorspace); /* Initialize the printer. */ (void) WriteBlobString(image,"\033E"); /* printer reset */ (void) WriteBlobString(image,"\033*r3F"); /* set presentation mode */ (void) FormatLocaleString(buffer,MaxTextExtent,"\033*r%.20gs%.20gT", (double) image->columns,(double) image->rows); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*t%.20gR",(double) density); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"\033&l0E"); /* top margin 0 */ if (IsMonochromeImage(image,&image->exception) != MagickFalse) { /* Monochrome image: use default printer monochrome setup. */ bits_per_pixel=1; } else if (image->storage_class == DirectClass) { /* DirectClass image. */ bits_per_pixel=24; (void) WriteBlobString(image,"\033*v6W"); /* set color mode */ (void) WriteBlobByte(image,0); /* RGB */ (void) WriteBlobByte(image,3); /* direct by pixel */ (void) WriteBlobByte(image,0); /* bits per index (ignored) */ (void) WriteBlobByte(image,8); /* bits per red component */ (void) WriteBlobByte(image,8); /* bits per green component */ (void) WriteBlobByte(image,8); /* bits per blue component */ } else { /* Colormapped image. */ bits_per_pixel=8; (void) WriteBlobString(image,"\033*v6W"); /* set color mode... */ (void) WriteBlobByte(image,0); /* RGB */ (void) WriteBlobByte(image,1); /* indexed by pixel */ (void) WriteBlobByte(image,bits_per_pixel); /* bits per index */ (void) WriteBlobByte(image,8); /* bits per red component */ (void) WriteBlobByte(image,8); /* bits per green component */ (void) WriteBlobByte(image,8); /* bits per blue component */ for (i=0; i < (ssize_t) image->colors; i++) { (void) FormatLocaleString(buffer,MaxTextExtent, "\033*v%da%db%dc%.20gI", ScaleQuantumToChar(image->colormap[i].red), ScaleQuantumToChar(image->colormap[i].green), ScaleQuantumToChar(image->colormap[i].blue),(double) i); (void) WriteBlobString(image,buffer); } for (one=1; i < (ssize_t) (one << bits_per_pixel); i++) { (void) FormatLocaleString(buffer,MaxTextExtent,"\033*v%.20gI", (double) i); (void) WriteBlobString(image,buffer); } } option=GetImageOption(image_info,"pcl:fit-to-page"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) (void) WriteBlobString(image,"\033*r3A"); else (void) WriteBlobString(image,"\033*r1A"); /* start raster graphics */ (void) WriteBlobString(image,"\033*b0Y"); /* set y offset */ length=(image->columns*bits_per_pixel+7)/8; pixels=(unsigned char *) AcquireQuantumMemory(length+1,sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) ResetMagickMemory(pixels,0,(length+1)*sizeof(*pixels)); compress_pixels=(unsigned char *) NULL; previous_pixels=(unsigned char *) NULL; switch (image->compression) { case NoCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b0M"); (void) WriteBlobString(image,buffer); break; } case RLECompression: { compress_pixels=(unsigned char *) AcquireQuantumMemory(length+256, sizeof(*compress_pixels)); if (compress_pixels == (unsigned char *) NULL) { pixels=(unsigned char *) RelinquishMagickMemory(pixels); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } (void) ResetMagickMemory(compress_pixels,0,(length+256)* sizeof(*compress_pixels)); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b2M"); (void) WriteBlobString(image,buffer); break; } default: { compress_pixels=(unsigned char *) AcquireQuantumMemory(3*length+256, sizeof(*compress_pixels)); if (compress_pixels == (unsigned char *) NULL) { pixels=(unsigned char *) RelinquishMagickMemory(pixels); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } (void) ResetMagickMemory(compress_pixels,0,(3*length+256)* sizeof(*compress_pixels)); previous_pixels=(unsigned char *) AcquireQuantumMemory(length+1, sizeof(*previous_pixels)); if (previous_pixels == (unsigned char *) NULL) { compress_pixels=(unsigned char *) RelinquishMagickMemory( compress_pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } (void) ResetMagickMemory(previous_pixels,0,(length+1)* sizeof(*previous_pixels)); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b3M"); (void) WriteBlobString(image,buffer); break; } } for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); if (p == (const PixelPacket *) NULL) break; indexes=GetAuthenticIndexQueue(image); q=pixels; switch (bits_per_pixel) { case 1: { register unsigned char bit, byte; /* Monochrome image. */ bit=0; byte=0; for (x=0; x < (ssize_t) image->columns; x++) { byte<<=1; if (GetPixelIntensity(image,p) < (QuantumRange/2.0)) byte|=0x01; bit++; if (bit == 8) { *q++=byte; bit=0; byte=0; } p++; } if (bit != 0) *q++=byte << (8-bit); break; } case 8: { /* Colormapped image. */ for (x=0; x < (ssize_t) image->columns; x++) *q++=(unsigned char) GetPixelIndex(indexes+x); break; } case 24: case 32: { /* Truecolor image. */ for (x=0; x < (ssize_t) image->columns; x++) { *q++=ScaleQuantumToChar(GetPixelRed(p)); *q++=ScaleQuantumToChar(GetPixelGreen(p)); *q++=ScaleQuantumToChar(GetPixelBlue(p)); p++; } break; } } switch (image->compression) { case NoCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b%.20gW", (double) length); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,length,pixels); break; } case RLECompression: { packets=PCLPackbitsCompressImage(length,pixels,compress_pixels); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b%.20gW", (double) packets); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,packets,compress_pixels); break; } default: { if (y == 0) for (i=0; i < (ssize_t) length; i++) previous_pixels[i]=(~pixels[i]); packets=PCLDeltaCompressImage(length,previous_pixels,pixels, compress_pixels); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b%.20gW", (double) packets); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,packets,compress_pixels); (void) CopyMagickMemory(previous_pixels,pixels,length* sizeof(*pixels)); break; } } } (void) WriteBlobString(image,"\033*rB"); /* end graphics */ switch (image->compression) { case NoCompression: break; case RLECompression: { compress_pixels=(unsigned char *) RelinquishMagickMemory( compress_pixels); break; } default: { previous_pixels=(unsigned char *) RelinquishMagickMemory( previous_pixels); compress_pixels=(unsigned char *) RelinquishMagickMemory( compress_pixels); break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) WriteBlobString(image,"\033E"); (void) CloseBlob(image); return(MagickTrue); }