Powered by Pair ImageMagick logo
Image Magick
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages

ImageMagick-6.1.1/coders/cin.c

Go to the documentation of this file.
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % CCCC IIIII N N % 00007 % C I NN N % 00008 % C I N N N % 00009 % C I N NN % 00010 % CCCC IIIII N N % 00011 % % 00012 % % 00013 % Read/Write Kodak Cineon Image Format. % 00014 % Cineon Image Format is a subset of SMTPE DPX % 00015 % % 00016 % % 00017 % Software Design % 00018 % John Cristy % 00019 % Kelly Bergougnoux % 00020 % October 2003 % 00021 % % 00022 % % 00023 % Copyright 1999-2004 ImageMagick Studio LLC, a non-profit organization % 00024 % dedicated to making software imaging solutions freely available. % 00025 % % 00026 % You may not use this file except in compliance with the License. You may % 00027 % obtain a copy of the License at % 00028 % % 00029 % http://www.imagemagick.org/www/Copyright.html % 00030 % % 00031 % Unless required by applicable law or agreed to in writing, software % 00032 % distributed under the License is distributed on an "AS IS" BASIS, % 00033 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00034 % See the License for the specific language governing permissions and % 00035 % limitations under the License. % 00036 % % 00037 % % 00038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00039 % 00040 % Cineon image file format draft is available at 00041 % http://www.cineon.com/ff_draft.php. 00042 % 00043 % 00044 */ 00045 00046 /* 00047 Include declarations. 00048 */ 00049 #include "magick/studio.h" 00050 #include "magick/blob.h" 00051 #include "magick/blob_private.h" 00052 #include "magick/colorspace.h" 00053 #include "magick/error.h" 00054 #include "magick/error_private.h" 00055 #include "magick/image.h" 00056 #include "magick/image_private.h" 00057 #include "magick/list.h" 00058 #include "magick/magick.h" 00059 #include "magick/memory_.h" 00060 #include "magick/monitor.h" 00061 #include "magick/static.h" 00062 #include "magick/string_.h" 00063 00064 /* 00065 Forward declaractions. 00066 */ 00067 static MagickBooleanType 00068 WriteCINImage(const ImageInfo *,Image *); 00069 00070 /* 00071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00072 % % 00073 % % 00074 % % 00075 % I s C I N E O N % 00076 % % 00077 % % 00078 % % 00079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00080 % 00081 % IsCIN() returns MagickTrue if the image format type, identified by the magick 00082 % string, is CIN. 00083 % 00084 % The format of the IsCIN method is: 00085 % 00086 % MagickBooleanType IsCIN(const unsigned char *magick,const size_t length) 00087 % 00088 % A description of each parameter follows: 00089 % 00090 % o magick: This string is generally the first few bytes of an image file 00091 % or blob. 00092 % 00093 % o length: Specifies the length of the magick string. 00094 % 00095 % 00096 */ 00097 static MagickBooleanType IsCIN(const unsigned char *magick,const size_t length) 00098 { 00099 if (length < 4) 00100 return(MagickFalse); 00101 if (memcmp(magick,"\200\052\137\327",4) == 0) 00102 return(MagickTrue); 00103 return(MagickFalse); 00104 } 00105 00106 /* 00107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00108 % % 00109 % % 00110 % % 00111 % R e a d C I N E O N I m a g e % 00112 % % 00113 % % 00114 % % 00115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00116 % 00117 % ReadCINImage() reads an CIN X image file and returns it. It allocates 00118 % the memory necessary for the new Image structure and returns a point to the 00119 % new image. 00120 % 00121 % The format of the ReadCINImage method is: 00122 % 00123 % Image *ReadCINImage(const ImageInfo *image_info, 00124 % ExceptionInfo *exception) 00125 % 00126 % A description of each parameter follows: 00127 % 00128 % o image_info: The image info. 00129 % 00130 % o exception: return any errors or warnings in this structure. 00131 % 00132 % 00133 */ 00134 static Image *ReadCINImage(const ImageInfo *image_info, 00135 ExceptionInfo *exception) 00136 { 00137 #define MonoColorType 1 00138 #define RGBColorType 3 00139 00140 char 00141 magick[4]; 00142 00143 Image 00144 *image; 00145 00146 long 00147 y; 00148 00149 MagickBooleanType 00150 status; 00151 00152 register long 00153 x; 00154 00155 register PixelPacket 00156 *q; 00157 00158 register long 00159 i; 00160 00161 ssize_t 00162 count; 00163 00164 unsigned char 00165 colortype; 00166 00167 unsigned long 00168 headersize, 00169 pixel; 00170 00171 /* 00172 Open image file. 00173 */ 00174 assert(image_info != (const ImageInfo *) NULL); 00175 assert(image_info->signature == MagickSignature); 00176 if (image_info->debug != MagickFalse) 00177 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image_info->filename); 00178 assert(exception != (ExceptionInfo *) NULL); 00179 assert(exception->signature == MagickSignature); 00180 image=AllocateImage(image_info); 00181 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); 00182 if (status == MagickFalse) 00183 { 00184 DestroyImageList(image); 00185 return((Image *) NULL); 00186 } 00187 /* 00188 Read CIN image. 00189 */ 00190 count=ReadBlob(image,4,(unsigned char *) magick); 00191 if ((count == 0) || 00192 ((LocaleNCompare((char *) magick,"\200\052\137\327",4) != 0))) 00193 ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 00194 headersize=ReadBlobMSBLong(image); 00195 for (i=0; i < 185; i++) 00196 (void) ReadBlobByte(image); 00197 colortype=(unsigned char) ReadBlobByte(image); 00198 for (i=0; i < 4; i++) 00199 (void) ReadBlobByte(image); 00200 image->depth=ReadBlobByte(image) > 8 ? 16UL : 8UL; 00201 (void) ReadBlobByte(image); 00202 image->columns= ReadBlobMSBLong(image); 00203 image->rows= ReadBlobMSBLong(image); 00204 (void) SeekBlob(image,(MagickOffsetType) headersize,SEEK_SET); 00205 if (image_info->ping) 00206 { 00207 CloseBlob(image); 00208 return(image); 00209 } 00210 /* 00211 Convert CIN raster image to pixel packets. 00212 */ 00213 switch ((int) colortype) 00214 { 00215 case (MonoColorType): 00216 { 00217 q=SetImagePixels(image,0,0,image->columns,image->rows); 00218 for (x=0; x < (long) ((image->columns*image->rows)/3); x++) 00219 { 00220 pixel=ReadBlobMSBLong(image); 00221 q->red=ScaleXToQuantum((pixel >> 0) & 0x3ff,1023); 00222 q->green=q->red; 00223 q->blue=q->red; 00224 q++; 00225 q->red=ScaleXToQuantum((pixel >> 10) & 0x3ff,1023); 00226 q->green=q->red; 00227 q->blue=q->red; 00228 q++; 00229 q->red=ScaleXToQuantum((pixel >> 20) & 0x3ff,1023); 00230 q->green=q->red; 00231 q->blue=q->red; 00232 q++; 00233 } 00234 break; 00235 } 00236 case (RGBColorType): 00237 { 00238 for (y=0; y < (long) image->rows; y++) 00239 { 00240 q=SetImagePixels(image,0,y,image->columns,1); 00241 if (q == (PixelPacket *) NULL) 00242 break; 00243 for (x=0; x < (long) image->columns; x++) 00244 { 00245 pixel=ReadBlobMSBLong(image); 00246 q->red=ScaleXToQuantum((pixel >> 22) & 0x3ff,1023); 00247 q->green=ScaleXToQuantum((pixel >> 12) & 0x3ff,1023); 00248 q->blue=ScaleXToQuantum((pixel >> 2) & 0x3ff,1023); 00249 q++; 00250 } 00251 if (!SyncImagePixels(image)) 00252 break; 00253 if (image->previous == (Image *) NULL) 00254 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 00255 (QuantumTick(y,image->rows) != MagickFalse)) 00256 { 00257 status=image->progress_monitor(LoadImageTag,y,image->rows, 00258 image->client_data); 00259 if (status == MagickFalse) 00260 break; 00261 } 00262 } 00263 break; 00264 } 00265 default: 00266 ThrowReaderException(CorruptImageError,"ColorTypeNotSupported"); 00267 } 00268 if (EOFBlob(image)) 00269 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", 00270 image->filename); 00271 CloseBlob(image); 00272 return(GetFirstImageInList(image)); 00273 } 00274 00275 /* 00276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00277 % % 00278 % % 00279 % % 00280 % R e g i s t e r C I N E O N I m a g e % 00281 % % 00282 % % 00283 % % 00284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00285 % 00286 % RegisterCINImage() adds attributes for the CIN image format to the list of 00287 % of supported formats. The attributes include the image format tag, a method 00288 % to read and/or write the format, whether the format supports the saving of 00289 % more than one frame to the same file or blob, whether the format supports 00290 % native in-memory I/O, and a brief description of the format. 00291 % 00292 % The format of the RegisterCINImage method is: 00293 % 00294 % RegisterCINImage(void) 00295 % 00296 */ 00297 ModuleExport void RegisterCINImage(void) 00298 { 00299 MagickInfo 00300 *entry; 00301 00302 entry=SetMagickInfo("CIN"); 00303 entry->decoder=(DecoderHandler *) ReadCINImage; 00304 entry->encoder=(EncoderHandler *) WriteCINImage; 00305 entry->magick=(MagickHandler *) IsCIN; 00306 entry->description=AcquireString("Cineon Image File"); 00307 entry->module=AcquireString("CIN"); 00308 (void) RegisterMagickInfo(entry); 00309 } 00310 00311 /* 00312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00313 % % 00314 % % 00315 % % 00316 % U n r e g i s t e r C I N E O N I m a g e % 00317 % % 00318 % % 00319 % % 00320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00321 % 00322 % UnregisterCINImage() removes format registrations made by the CIN module 00323 % from the list of supported formats. 00324 % 00325 % The format of the UnregisterCINImage method is: 00326 % 00327 % UnregisterCINImage(void) 00328 % 00329 */ 00330 ModuleExport void UnregisterCINImage(void) 00331 { 00332 (void) UnregisterMagickInfo("CINEON"); 00333 } 00334 00335 /* 00336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00337 % % 00338 % % 00339 % % 00340 % W r i t e C I N E O N I m a g e % 00341 % % 00342 % % 00343 % % 00344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00345 % 00346 % WriteCINImage() writes an image in CIN encoded image format. 00347 % 00348 % The format of the WriteCINImage method is: 00349 % 00350 % MagickBooleanType WriteCINImage(const ImageInfo *image_info,Image *image) 00351 % 00352 % A description of each parameter follows. 00353 % 00354 % o image_info: The image info. 00355 % 00356 % o image: The image. 00357 % 00358 % 00359 */ 00360 static MagickBooleanType WriteCINImage(const ImageInfo *image_info,Image *image) 00361 { 00362 long 00363 y; 00364 00365 MagickBooleanType 00366 status; 00367 00368 register const PixelPacket 00369 *p; 00370 00371 register long 00372 i, 00373 x; 00374 00375 unsigned long 00376 pixel; 00377 00378 unsigned long 00379 maxb, 00380 maxg, 00381 maxr, 00382 minb, 00383 ming, 00384 minr; 00385 00386 /* 00387 Get the max values for each component... I guess it "needs" it... 00388 */ 00389 maxr=maxg=maxb=0; 00390 minr=ming=minb=MaxRGB; 00391 for (y=0; y < (long) image->rows; y++) 00392 { 00393 p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); 00394 if (p == (const PixelPacket *) NULL) 00395 break; 00396 for (x=0; x < (long) image->columns; x++) 00397 { 00398 if ( (unsigned long) p->red > maxr ) maxr = p->red; 00399 if ( (unsigned long) p->green > maxg ) maxg = p->green; 00400 if ( (unsigned long) p->blue > maxb ) maxb = p->blue; 00401 if ( (unsigned long) p->red < minr ) minr = p->red; 00402 if ( (unsigned long) p->green < ming ) ming = p->green; 00403 if ( (unsigned long) p->blue < minb ) minb = p->blue; 00404 p++; 00405 } 00406 } 00407 /* 00408 Div by 64 to get 10bit values since that's all I'll do right now. 00409 */ 00410 maxr/=64; 00411 maxg/=64; 00412 maxb/=64; 00413 minr/=64; 00414 ming/=64; 00415 minb/=64; 00416 /* 00417 Open output image file. 00418 */ 00419 assert(image_info != (const ImageInfo *) NULL); 00420 assert(image_info->signature == MagickSignature); 00421 assert(image != (Image *) NULL); 00422 assert(image->signature == MagickSignature); 00423 if (image->debug != MagickFalse) 00424 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 00425 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); 00426 if (status == MagickFalse) 00427 return(status); 00428 /* Magick Number... */ 00429 (void) SetImageColorspace(image,RGBColorspace); 00430 (void) WriteBlobMSBLong(image,0x802A5FD7UL); 00431 /* Offset to image */ 00432 (void) WriteBlobMSBLong(image,0x0800); 00433 /* Generic section header length */ 00434 (void) WriteBlobMSBLong(image,0x400); 00435 /* Industry Specific lenght */ 00436 (void) WriteBlobMSBLong(image,0x400); 00437 /* variable length section */ 00438 (void) WriteBlobMSBLong(image,0x0); 00439 /* Total image file size */ 00440 (void) WriteBlobMSBLong(image,4*image->columns*image->rows+0x2000); 00441 /* Version number of header format */ 00442 (void) WriteBlobString(image,"V4.5"); 00443 (void) WriteBlobMSBLong(image,0x0); 00444 /* Filename */ 00445 (void) WriteBlobString(image,image->filename); 00446 for ( i =0 ; i < (long) (100-strlen(image->filename)); i++ ) 00447 (void) WriteBlobByte(image,0); 00448 /* Creation Date. */ 00449 (void) WriteBlobString(image,"yyyy:mm:dd "); 00450 /* Creation Time. */ 00451 (void) WriteBlobString(image,"hh:mm:ssxxx "); 00452 for ( i =0 ; i < 36 ; i++) 00453 (void) WriteBlobByte(image,0); 00454 /* 0 left to right top to bottom */ 00455 (void) WriteBlobByte(image,0); 00456 /* 3 channels */ 00457 (void) WriteBlobByte(image,3); 00458 /* alignment */ 00459 (void) WriteBlobByte(image,0x0); 00460 (void) WriteBlobByte(image,0x0); 00461 /* Do R */ 00462 /* Channel 1 designator byte 0 */ 00463 (void) WriteBlobByte(image,0); 00464 /* Channel 1 designator byte 1 */ 00465 (void) WriteBlobByte(image,1); 00466 /* Bits per pixel... */ 00467 (void) WriteBlobByte(image,10); 00468 /* alignment */ 00469 (void) WriteBlobByte(image,0); 00470 /* pixels per line */ 00471 (void) WriteBlobMSBLong(image,image->columns); 00472 /* lines per image */ 00473 (void) WriteBlobMSBLong(image,image->rows); 00474 /* Minimum data value */ 00475 (void) WriteBlobMSBLong(image,minr); 00476 /* Minimum quantity represented */ 00477 (void) WriteBlobMSBLong(image,0x0); 00478 /* Maximum data value */ 00479 (void) WriteBlobMSBLong(image,maxr); 00480 /* Maximum quantity represented */ 00481 (void) WriteBlobMSBLong(image,0x40000000); 00482 /* Do G */ 00483 /* see above. */ 00484 (void) WriteBlobByte(image,0); 00485 (void) WriteBlobByte(image,2); 00486 (void) WriteBlobByte(image,10); 00487 (void) WriteBlobByte(image,0); 00488 (void) WriteBlobMSBLong(image,image->columns); 00489 (void) WriteBlobMSBLong(image,image->rows); 00490 (void) WriteBlobMSBLong(image,ming); 00491 (void) WriteBlobMSBLong(image,0x0); 00492 (void) WriteBlobMSBLong(image,maxg); 00493 (void) WriteBlobMSBLong(image,0x40000000); 00494 /* Go B */ 00495 /* see above. */ 00496 (void) WriteBlobByte(image,0); 00497 (void) WriteBlobByte(image,3); 00498 (void) WriteBlobByte(image,10); 00499 (void) WriteBlobByte(image,0); 00500 (void) WriteBlobMSBLong(image,image->columns); 00501 (void) WriteBlobMSBLong(image,image->rows); 00502 (void) WriteBlobMSBLong(image,minb); 00503 (void) WriteBlobMSBLong(image,0x0); 00504 (void) WriteBlobMSBLong(image,maxb); 00505 (void) WriteBlobMSBLong(image,0x40000000); 00506 /* pad channel 4-8 */ 00507 for (i=0; i < 5*28; i++) 00508 (void) WriteBlobByte(image,0x00); 00509 /* k here's where it gets ugly and I should be shot */ 00510 /* White point(colour temp.) x */ 00511 (void) WriteBlobMSBLong(image,0x4EFF0000); 00512 /* White point(colour temp.) y */ 00513 (void) WriteBlobMSBLong(image,0x4EFF0000); 00514 /* Red primary chromaticity x */ 00515 (void) WriteBlobMSBLong(image,0x4EFF0000); 00516 /* Red primary chromaticity y */ 00517 (void) WriteBlobMSBLong(image,0x4EFF0000); 00518 /* Green primary chromaticity x */ 00519 (void) WriteBlobMSBLong(image,0x4EFF0000); 00520 /* Green primary chromaticity y */ 00521 (void) WriteBlobMSBLong(image,0x4EFF0000); 00522 /* Blue primary chromaticity x */ 00523 (void) WriteBlobMSBLong(image,0x4EFF0000); 00524 /* Blue primary chromaticity y */ 00525 (void) WriteBlobMSBLong(image,0x4EFF0000); 00526 /* Label Text... */ 00527 for (i=0; i < 200+28; i++) 00528 (void) WriteBlobByte(image,0x00); 00529 /* pixel interleave (rgbrgbr...) */ 00530 (void) WriteBlobByte(image,0); 00531 /* Packing longword (32bit) boundaries */ 00532 (void) WriteBlobByte(image,5); 00533 /* Data unsigned */ 00534 (void) WriteBlobByte(image,0); 00535 /* Image sense: positive image */ 00536 (void) WriteBlobByte(image,0); 00537 /* End of line padding */ 00538 (void) WriteBlobMSBLong(image,0x0); 00539 /* End of channel padding */ 00540 (void) WriteBlobMSBLong(image,0x0); 00541 /* Reseved for future Use.. */ 00542 for (i=0; i < 20; i++) 00543 (void) WriteBlobByte(image,0x00); 00544 /* X offset */ 00545 (void) WriteBlobMSBLong(image,0x0); 00546 /* Y offset */ 00547 (void) WriteBlobMSBLong(image,0x0); 00548 /* Filename */ 00549 (void) WriteBlobString(image,image->filename); 00550 for ( i =0 ; i < (long) (100-strlen(image->filename)); i++ ) 00551 (void) WriteBlobByte(image,0); 00552 /* date. who cares ? */ 00553 for ( i =0 ; i < 12 ; i++ ) 00554 (void) WriteBlobByte(image,0); 00555 /* time who cares ? */ 00556 for ( i =0 ; i < 12 ; i++ ) 00557 (void) WriteBlobByte(image,0); 00558 (void) WriteBlobString(image,"ImageMagick"); 00559 for (i = 0; i < 64-11 ; i++) 00560 (void) WriteBlobByte(image,0); 00561 for (i = 0; i < 32 ; i++) 00562 (void) WriteBlobByte(image,0); 00563 for (i = 0; i < 32 ; i++) 00564 (void) WriteBlobByte(image,0); 00565 /* X input device pitch */ 00566 (void) WriteBlobMSBLong(image,0x4326AB85); 00567 /* Y input device pitch */ 00568 (void) WriteBlobMSBLong(image,0x4326AB85); 00569 /* Image gamma */ 00570 (void) WriteBlobMSBLong(image,0x3F800000); 00571 /* Reserved for future use */ 00572 for (i = 0; i < 40 ; i++) 00573 (void) WriteBlobByte(image,0); 00574 for ( i = 0 ; i < 4 ; i++) 00575 (void) WriteBlobByte(image,0); 00576 (void) WriteBlobMSBLong(image,0x0); 00577 (void) WriteBlobMSBLong(image,0x0); 00578 for ( i = 0 ; i < 32 ; i++) 00579 (void) WriteBlobByte(image,0); 00580 (void) WriteBlobMSBLong(image,0x0); 00581 (void) WriteBlobMSBLong(image,0x0); 00582 for ( i = 0 ; i < 32 ; i++) 00583 (void) WriteBlobByte(image,0); 00584 for ( i = 0 ; i < 200 ; i++) 00585 (void) WriteBlobByte(image,0); 00586 for ( i = 0 ; i < 740 ; i++) 00587 (void) WriteBlobByte(image,0); 00588 /* 00589 Convert pixel packets to CIN raster image. 00590 */ 00591 for (y=0; y < (long) image->rows; y++) 00592 { 00593 p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); 00594 if (p == (const PixelPacket *) NULL) 00595 break; 00596 for (x=0; x < (long) image->columns; x++) 00597 { 00598 pixel=(unsigned long) 00599 (((long) ((1023L*p->red+MaxRGB/2)/MaxRGB) & 0x3ff) << 22) | 00600 (((long) ((1023L*p->green+MaxRGB/2)/MaxRGB) &0x3ff) << 12) | 00601 (((long) ((1023L*p->blue+MaxRGB/2)/MaxRGB) &0x3ff) << 2); 00602 (void) WriteBlobMSBLong(image,pixel); 00603 p++; 00604 } 00605 } 00606 CloseBlob(image); 00607 return(status); 00608 }

Generated on Mon Oct 25 13:40:35 2004 for ImageMagick by doxygen 1.3.7
ImageMagick Copyright © 2004, ImageMagick Studio LLC