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/fpx.c

Go to the documentation of this file.
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % FFFFF PPPP X X % 00007 % F P P X X % 00008 % FFF PPPP X % 00009 % F P X X % 00010 % F P X X % 00011 % % 00012 % % 00013 % Read/Write FlashPIX Image Format. % 00014 % % 00015 % Software Design % 00016 % John Cristy % 00017 % July 1992 % 00018 % % 00019 % % 00020 % Copyright 1999-2004 ImageMagick Studio LLC, a non-profit organization % 00021 % dedicated to making software imaging solutions freely available. % 00022 % % 00023 % You may not use this file except in compliance with the License. You may % 00024 % obtain a copy of the License at % 00025 % % 00026 % http://www.imagemagick.org/www/Copyright.html % 00027 % % 00028 % Unless required by applicable law or agreed to in writing, software % 00029 % distributed under the License is distributed on an "AS IS" BASIS, % 00030 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00031 % See the License for the specific language governing permissions and % 00032 % limitations under the License. % 00033 % % 00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00035 % 00036 % 00037 */ 00038 00039 /* 00040 Include declarations. 00041 */ 00042 #include "magick/studio.h" 00043 #include "magick/attribute.h" 00044 #include "magick/blob.h" 00045 #include "magick/blob_private.h" 00046 #include "magick/color.h" 00047 #include "magick/color_private.h" 00048 #include "magick/colorspace.h" 00049 #include "magick/constitute.h" 00050 #include "magick/error.h" 00051 #include "magick/error_private.h" 00052 #include "magick/geometry.h" 00053 #include "magick/image.h" 00054 #include "magick/image_private.h" 00055 #include "magick/list.h" 00056 #include "magick/magick.h" 00057 #include "magick/memory_.h" 00058 #include "magick/monitor.h" 00059 #include "magick/static.h" 00060 #include "magick/string_.h" 00061 #if defined(HasFPX) 00062 #if !defined(vms) && !defined(macintosh) && !defined(__WINDOWS__) 00063 #include <fpxlib.h> 00064 #else 00065 #include "Fpxlib.h" 00066 #endif 00067 #endif 00068 00069 #if defined(HasFPX) 00070 /* 00071 Forward declarations. 00072 */ 00073 static MagickBooleanType 00074 WriteFPXImage(const ImageInfo *,Image *); 00075 #endif 00076 00077 /* 00078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00079 % % 00080 % % 00081 % % 00082 % I s F P X % 00083 % % 00084 % % 00085 % % 00086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00087 % 00088 % IsFPX() returns MagickTrue if the image format type, identified by the 00089 % magick string, is FPX. 00090 % 00091 % The format of the IsFPX method is: 00092 % 00093 % MagickBooleanType IsFPX(const unsigned char *magick,const size_t length) 00094 % 00095 % A description of each parameter follows: 00096 % 00097 % o magick: This string is generally the first few bytes of an image file 00098 % or blob. 00099 % 00100 % o length: Specifies the length of the magick string. 00101 % 00102 % 00103 */ 00104 static MagickBooleanType IsFPX(const unsigned char *magick,const size_t length) 00105 { 00106 if (length < 4) 00107 return(MagickFalse); 00108 if (memcmp(magick,"\320\317\021\340",4) == 0) 00109 return(MagickTrue); 00110 return(MagickFalse); 00111 } 00112 00113 #if defined(HasFPX) 00114 /* 00115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00116 % % 00117 % % 00118 % % 00119 % R e a d F P X I m a g e % 00120 % % 00121 % % 00122 % % 00123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00124 % 00125 % ReadFPXImage() reads a FlashPix image file and returns it. It 00126 % allocates the memory necessary for the new Image structure and returns a 00127 % pointer to the new image. This method was contributed by BillR@corbis.com. 00128 % 00129 % The format of the ReadFPXImage method is: 00130 % 00131 % Image *ReadFPXImage(const ImageInfo *image_info,ExceptionInfo *exception) 00132 % 00133 % A description of each parameter follows: 00134 % 00135 % o image_info: The image info. 00136 % 00137 % o exception: return any errors or warnings in this structure. 00138 % 00139 % 00140 */ 00141 static Image *ReadFPXImage(const ImageInfo *image_info,ExceptionInfo *exception) 00142 { 00143 FPXColorspace 00144 colorspace; 00145 00146 FPXImageComponentDesc 00147 *alpha_component, 00148 *blue_component, 00149 *green_component, 00150 *red_component; 00151 00152 FPXImageDesc 00153 fpx_info; 00154 00155 FPXImageHandle 00156 *flashpix; 00157 00158 FPXStatus 00159 fpx_status; 00160 00161 FPXSummaryInformation 00162 summary_info; 00163 00164 Image 00165 *image; 00166 00167 IndexPacket 00168 index; 00169 00170 long 00171 y; 00172 00173 MagickBooleanType 00174 status; 00175 00176 register IndexPacket 00177 *indexes; 00178 00179 register long 00180 i, 00181 x; 00182 00183 register PixelPacket 00184 *q; 00185 00186 register unsigned char 00187 *a, 00188 *b, 00189 *g, 00190 *r; 00191 00192 unsigned char 00193 *scanline; 00194 00195 unsigned long 00196 height, 00197 memory_limit, 00198 scene, 00199 tile_width, 00200 tile_height, 00201 width; 00202 00203 /* 00204 Open image. 00205 */ 00206 assert(image_info != (const ImageInfo *) NULL); 00207 assert(image_info->signature == MagickSignature); 00208 if (image_info->debug != MagickFalse) 00209 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image_info->filename); 00210 assert(exception != (ExceptionInfo *) NULL); 00211 assert(exception->signature == MagickSignature); 00212 image=AllocateImage(image_info); 00213 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); 00214 if (status == MagickFalse) 00215 { 00216 DestroyImageList(image); 00217 return((Image *) NULL); 00218 } 00219 CloseBlob(image); 00220 /* 00221 Initialize FPX toolkit. 00222 */ 00223 fpx_status=FPX_InitSystem(); 00224 if (fpx_status != FPX_OK) 00225 ThrowReaderException(CoderError,"UnableToInitializeFPXLibrary"); 00226 memory_limit=20000000; 00227 fpx_status=FPX_SetToolkitMemoryLimit(&memory_limit); 00228 if (fpx_status != FPX_OK) 00229 { 00230 FPX_ClearSystem(); 00231 ThrowReaderException(CoderError,"UnableToInitializeFPXLibrary"); 00232 } 00233 tile_width=64; 00234 tile_height=64; 00235 flashpix=(FPXImageHandle *) NULL; 00236 { 00237 #if defined(macintosh) 00238 FSSpec 00239 fsspec; 00240 00241 FilenameToFSSpec(image->filename,&fsspec); 00242 fpx_status=FPX_OpenImageByFilename((const FSSpec &) fsspec,(char *) NULL, 00243 #else 00244 fpx_status=FPX_OpenImageByFilename(image->filename,(char *) NULL, 00245 #endif 00246 &width,&height,&tile_width,&tile_height,&colorspace,&flashpix); 00247 } 00248 if (fpx_status == FPX_LOW_MEMORY_ERROR) 00249 { 00250 FPX_ClearSystem(); 00251 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 00252 } 00253 if (fpx_status != FPX_OK) 00254 { 00255 FPX_ClearSystem(); 00256 ThrowFileException(exception,FileOpenError,"UnableToOpenFile", 00257 image->filename); 00258 DestroyImageList(image); 00259 return((Image *) NULL); 00260 } 00261 if (colorspace.numberOfComponents == 0) 00262 { 00263 FPX_ClearSystem(); 00264 ThrowReaderException(CorruptImageError,"ImageTypeNotSupported"); 00265 } 00266 if (image_info->view == (char *) NULL) 00267 { 00268 float 00269 aspect_ratio; 00270 00271 /* 00272 Get the aspect ratio. 00273 */ 00274 aspect_ratio=(float) width/height; 00275 fpx_status=FPX_GetImageResultAspectRatio(flashpix,&aspect_ratio); 00276 if (fpx_status != FPX_OK) 00277 ThrowReaderException(DelegateError,"UnableToReadAspectRatio"); 00278 if (width != (unsigned long) ((aspect_ratio*height)+0.5)) 00279 Swap(width,height); 00280 } 00281 fpx_status=FPX_GetSummaryInformation(flashpix,&summary_info); 00282 if (fpx_status != FPX_OK) 00283 { 00284 FPX_ClearSystem(); 00285 ThrowReaderException(DelegateError,"UnableToReadSummaryInfo"); 00286 } 00287 if (summary_info.title_valid) 00288 if ((summary_info.title.length != 0) && 00289 (summary_info.title.ptr != (unsigned char *) NULL)) 00290 { 00291 char 00292 *label; 00293 00294 /* 00295 Note image label. 00296 */ 00297 label=(char *) 00298 AcquireMagickMemory(summary_info.title.length+MaxTextExtent); 00299 if (label == (char *) NULL) 00300 { 00301 FPX_ClearSystem(); 00302 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 00303 } 00304 (void) CopyMagickString(label,(char *) summary_info.title.ptr, 00305 summary_info.title.length+1); 00306 (void) SetImageAttribute(image,"label",label); 00307 label=(char *) RelinquishMagickMemory(label); 00308 } 00309 if (summary_info.comments_valid) 00310 if ((summary_info.comments.length != 0) && 00311 (summary_info.comments.ptr != (unsigned char *) NULL)) 00312 { 00313 char 00314 *comments; 00315 00316 /* 00317 Note image comment. 00318 */ 00319 comments=(char *) 00320 AcquireMagickMemory(summary_info.comments.length+MaxTextExtent); 00321 if (comments == (char *) NULL) 00322 { 00323 FPX_ClearSystem(); 00324 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 00325 } 00326 (void) CopyMagickString(comments,(char *) summary_info.comments.ptr, 00327 summary_info.comments.length+1); 00328 (void) SetImageAttribute(image,"Comment",comments); 00329 comments=(char *) RelinquishMagickMemory(comments); 00330 } 00331 /* 00332 Determine resolution by scene specification. 00333 */ 00334 for (i=1; ; i++) 00335 if (((width >> i) < tile_width) || ((height >> i) < tile_height)) 00336 break; 00337 scene=i; 00338 if (image_info->number_scenes != 0) 00339 while (scene > image_info->scene) 00340 { 00341 width>>=1; 00342 height>>=1; 00343 scene--; 00344 } 00345 if (image_info->size != (char *) NULL) 00346 while ((width > image->columns) || (height > image->rows)) 00347 { 00348 width>>=1; 00349 height>>=1; 00350 scene--; 00351 } 00352 image->depth=8; 00353 image->columns=width; 00354 image->rows=height; 00355 if ((colorspace.numberOfComponents % 2) == 0) 00356 image->matte=MagickTrue; 00357 if (colorspace.numberOfComponents == 1) 00358 { 00359 /* 00360 Create linear colormap. 00361 */ 00362 if (AllocateImageColormap(image,MaxColormapSize) == MagickFalse) 00363 { 00364 FPX_ClearSystem(); 00365 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 00366 } 00367 } 00368 if (image_info->ping != MagickFalse) 00369 { 00370 (void) FPX_CloseImage(flashpix); 00371 FPX_ClearSystem(); 00372 return(GetFirstImageInList(image)); 00373 } 00374 /* 00375 Allocate memory for the image and pixel buffer. 00376 */ 00377 scanline=(unsigned char *) AcquireMagickMemory(colorspace.numberOfComponents* 00378 image->columns*(tile_height+1)); 00379 if (scanline == (unsigned char *) NULL) 00380 { 00381 FPX_ClearSystem(); 00382 (void) FPX_CloseImage(flashpix); 00383 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 00384 } 00385 /* 00386 Initialize FlashPix image description. 00387 */ 00388 fpx_info.numberOfComponents=colorspace.numberOfComponents; 00389 for (i=0; i < 4; i++) 00390 { 00391 fpx_info.components[i].myColorType.myDataType=DATA_TYPE_UNSIGNED_BYTE; 00392 fpx_info.components[i].horzSubSampFactor=1; 00393 fpx_info.components[i].vertSubSampFactor=1; 00394 fpx_info.components[i].columnStride=fpx_info.numberOfComponents; 00395 fpx_info.components[i].lineStride= 00396 image->columns*fpx_info.components[i].columnStride; 00397 fpx_info.components[i].theData=scanline+i; 00398 } 00399 fpx_info.components[0].myColorType.myColor= 00400 fpx_info.numberOfComponents > 2 ? NIFRGB_R : MONOCHROME; 00401 red_component=(&fpx_info.components[0]); 00402 fpx_info.components[1].myColorType.myColor= 00403 fpx_info.numberOfComponents > 2 ? NIFRGB_G : ALPHA; 00404 green_component=(&fpx_info.components[1]); 00405 fpx_info.components[2].myColorType.myColor=NIFRGB_B; 00406 blue_component=(&fpx_info.components[2]); 00407 fpx_info.components[3].myColorType.myColor=ALPHA; 00408 alpha_component=(&fpx_info.components[fpx_info.numberOfComponents-1]); 00409 FPX_SetResampleMethod(FPX_LINEAR_INTERPOLATION); 00410 /* 00411 Initialize image pixels. 00412 */ 00413 for (y=0; y < (long) image->rows; y++) 00414 { 00415 q=SetImagePixels(image,0,y,image->columns,1); 00416 if (q == (PixelPacket *) NULL) 00417 break; 00418 indexes=GetIndexes(image); 00419 if ((y % tile_height) == 0) 00420 { 00421 /* 00422 Read FPX image tile (with or without viewing affine).. 00423 */ 00424 if (image_info->view != (char *) NULL) 00425 fpx_status=FPX_ReadImageRectangle(flashpix,0,y,image->columns,y+ 00426 tile_height-1,scene,&fpx_info); 00427 else 00428 fpx_status=FPX_ReadImageTransformRectangle(flashpix,0.0F, 00429 (float) y/image->rows,(float) image->columns/image->rows, 00430 (float) (y+tile_height-1)/image->rows,(long) image->columns, 00431 (long) tile_height,&fpx_info); 00432 if (fpx_status == FPX_LOW_MEMORY_ERROR) 00433 { 00434 scanline=(char *) RelinquishMagickMemory(scanline); 00435 (void) FPX_CloseImage(flashpix); 00436 FPX_ClearSystem(); 00437 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 00438 } 00439 } 00440 /* 00441 Transfer a FPX scanline. 00442 */ 00443 r=red_component->theData+(y % tile_height)*red_component->lineStride; 00444 g=green_component->theData+(y % tile_height)*green_component->lineStride; 00445 b=blue_component->theData+(y % tile_height)*blue_component->lineStride; 00446 a=alpha_component->theData+(y % tile_height)*alpha_component->lineStride; 00447 for (x=0; x < (long) image->columns; x++) 00448 { 00449 if (fpx_info.numberOfComponents > 2) 00450 { 00451 q->red=ScaleCharToQuantum(*r); 00452 q->green=ScaleCharToQuantum(*g); 00453 q->blue=ScaleCharToQuantum(*b); 00454 } 00455 else 00456 { 00457 index=ScaleCharToQuantum(*r); 00458 indexes[x]=index; 00459 q->red=index; 00460 q->green=index; 00461 q->blue=index; 00462 } 00463 if (image->matte != MagickFalse) 00464 q->opacity=ScaleCharToQuantum(255-*a); 00465 q++; 00466 r+=red_component->columnStride; 00467 g+=green_component->columnStride; 00468 b+=blue_component->columnStride; 00469 a+=alpha_component->columnStride; 00470 } 00471 if (SyncImagePixels(image) == MagickFalse) 00472 break; 00473 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 00474 (QuantumTick(y,image->rows) != MagickFalse)) 00475 { 00476 status=image->progress_monitor(LoadImageTag,y,image->rows, 00477 image->client_data); 00478 if (status == MagickFalse) 00479 break; 00480 } 00481 } 00482 scanline=(char *) RelinquishMagickMemory(scanline); 00483 (void) FPX_CloseImage(flashpix); 00484 FPX_ClearSystem(); 00485 return(GetFirstImageInList(image)); 00486 } 00487 #endif 00488 00489 /* 00490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00491 % % 00492 % % 00493 % % 00494 % R e g i s t e r F P X I m a g e % 00495 % % 00496 % % 00497 % % 00498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00499 % 00500 % RegisterFPXImage() adds attributes for the FPX image format to 00501 % the list of supported formats. The attributes include the image format 00502 % tag, a method to read and/or write the format, whether the format 00503 % supports the saving of more than one frame to the same file or blob, 00504 % whether the format supports native in-memory I/O, and a brief 00505 % description of the format. 00506 % 00507 % The format of the RegisterFPXImage method is: 00508 % 00509 % RegisterFPXImage(void) 00510 % 00511 */ 00512 ModuleExport void RegisterFPXImage(void) 00513 { 00514 MagickInfo 00515 *entry; 00516 00517 entry=SetMagickInfo("FPX"); 00518 #if defined(HasFPX) 00519 entry->decoder=(DecoderHandler *) ReadFPXImage; 00520 entry->encoder=(EncoderHandler *) WriteFPXImage; 00521 #endif 00522 entry->adjoin=MagickFalse; 00523 entry->seekable_stream=MagickTrue; 00524 entry->magick=(MagickHandler *) IsFPX; 00525 entry->description=AcquireString("FlashPix Format"); 00526 entry->module=AcquireString("FPX"); 00527 (void) RegisterMagickInfo(entry); 00528 } 00529 00530 /* 00531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00532 % % 00533 % % 00534 % % 00535 % U n r e g i s t e r F P X I m a g e % 00536 % % 00537 % % 00538 % % 00539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00540 % 00541 % UnregisterFPXImage() removes format registrations made by the 00542 % FPX module from the list of supported formats. 00543 % 00544 % The format of the UnregisterFPXImage method is: 00545 % 00546 % UnregisterFPXImage(void) 00547 % 00548 */ 00549 ModuleExport void UnregisterFPXImage(void) 00550 { 00551 (void) UnregisterMagickInfo("FPX"); 00552 } 00553 00554 #if defined(HasFPX) 00555 /* 00556 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00557 % % 00558 % % 00559 % % 00560 % W r i t e F P X I m a g e % 00561 % % 00562 % % 00563 % % 00564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00565 % 00566 % WriteFPXImage() writes an image in the FlashPix image format. This 00567 % method was contributed by BillR@corbis.com. 00568 % 00569 % The format of the WriteFPXImage method is: 00570 % 00571 % MagickBooleanType WriteFPXImage(const ImageInfo *image_info,Image *image) 00572 % 00573 % A description of each parameter follows. 00574 % 00575 % o image_info: The image info. 00576 % 00577 % o image: The image. 00578 % 00579 % 00580 */ 00581 00582 static void ColorTwistMultiply(FPXColorTwistMatrix first, 00583 FPXColorTwistMatrix second,FPXColorTwistMatrix *color_twist) 00584 { 00585 /* 00586 Matrix multiply. 00587 */ 00588 assert(color_twist != (FPXColorTwistMatrix *) NULL); 00589 color_twist->byy=(first.byy*second.byy)+(first.byc1*second.bc1y)+ 00590 (first.byc2*second.bc2y)+(first.dummy1_zero*second.dummy4_zero); 00591 color_twist->byc1=(first.byy*second.byc1)+(first.byc1*second.bc1c1)+ 00592 (first.byc2*second.bc2c1)+(first.dummy1_zero*second.dummy5_zero); 00593 color_twist->byc2=(first.byy*second.byc2)+(first.byc1*second.bc1c2)+ 00594 (first.byc2*second.bc2c2)+(first.dummy1_zero*second.dummy6_zero); 00595 color_twist->dummy1_zero=(first.byy*second.dummy1_zero)+ 00596 (first.byc1*second.dummy2_zero)+(first.byc2*second.dummy3_zero)+ 00597 (first.dummy1_zero*second.dummy7_one); 00598 color_twist->bc1y=(first.bc1y*second.byy)+(first.bc1c1*second.bc1y)+ 00599 (first.bc1c2*second.bc2y)+(first.dummy2_zero*second.dummy4_zero); 00600 color_twist->bc1c1=(first.bc1y*second.byc1)+(first.bc1c1*second.bc1c1)+ 00601 (first.bc1c2*second.bc2c1)+(first.dummy2_zero*second.dummy5_zero); 00602 color_twist->bc1c2=(first.bc1y*second.byc2)+(first.bc1c1*second.bc1c2)+ 00603 (first.bc1c2*second.bc2c2)+(first.dummy2_zero*second.dummy6_zero); 00604 color_twist->dummy2_zero=(first.bc1y*second.dummy1_zero)+ 00605 (first.bc1c1*second.dummy2_zero)+(first.bc1c2*second.dummy3_zero)+ 00606 (first.dummy2_zero*second.dummy7_one); 00607 color_twist->bc2y=(first.bc2y*second.byy)+(first.bc2c1*second.bc1y)+ 00608 (first.bc2c2*second.bc2y)+(first.dummy3_zero*second.dummy4_zero); 00609 color_twist->bc2c1=(first.bc2y*second.byc1)+(first.bc2c1*second.bc1c1)+ 00610 (first.bc2c2*second.bc2c1)+(first.dummy3_zero*second.dummy5_zero); 00611 color_twist->bc2c2=(first.bc2y*second.byc2)+(first.bc2c1*second.bc1c2)+ 00612 (first.bc2c2*second.bc2c2)+(first.dummy3_zero*second.dummy6_zero); 00613 color_twist->dummy3_zero=(first.bc2y*second.dummy1_zero)+ 00614 (first.bc2c1*second.dummy2_zero)+(first.bc2c2*second.dummy3_zero)+ 00615 (first.dummy3_zero*second.dummy7_one); 00616 color_twist->dummy4_zero=(first.dummy4_zero*second.byy)+ 00617 (first.dummy5_zero*second.bc1y)+(first.dummy6_zero*second.bc2y)+ 00618 (first.dummy7_one*second.dummy4_zero); 00619 color_twist->dummy5_zero=(first.dummy4_zero*second.byc1)+ 00620 (first.dummy5_zero*second.bc1c1)+(first.dummy6_zero*second.bc2c1)+ 00621 (first.dummy7_one*second.dummy5_zero); 00622 color_twist->dummy6_zero=(first.dummy4_zero*second.byc2)+ 00623 (first.dummy5_zero*second.bc1c2)+(first.dummy6_zero*second.bc2c2)+ 00624 (first.dummy7_one*second.dummy6_zero); 00625 color_twist->dummy7_one=(first.dummy4_zero*second.dummy1_zero)+ 00626 (first.dummy5_zero*second.dummy2_zero)+ 00627 (first.dummy6_zero*second.dummy3_zero)+(first.dummy7_one*second.dummy7_one); 00628 } 00629 00630 static void SetBrightness(double brightness,FPXColorTwistMatrix *color_twist) 00631 { 00632 FPXColorTwistMatrix 00633 effect, 00634 result; 00635 00636 /* 00637 Set image brightness in color twist matrix. 00638 */ 00639 assert(color_twist != (FPXColorTwistMatrix *) NULL); 00640 brightness=sqrt((double) brightness); 00641 effect.byy=brightness; 00642 effect.byc1=0.0; 00643 effect.byc2=0.0; 00644 effect.dummy1_zero=0.0; 00645 effect.bc1y=0.0; 00646 effect.bc1c1=brightness; 00647 effect.bc1c2=0.0; 00648 effect.dummy2_zero=0.0; 00649 effect.bc2y=0.0; 00650 effect.bc2c1=0.0; 00651 effect.bc2c2=brightness; 00652 effect.dummy3_zero=0.0; 00653 effect.dummy4_zero=0.0; 00654 effect.dummy5_zero=0.0; 00655 effect.dummy6_zero=0.0; 00656 effect.dummy7_one=1.0; 00657 ColorTwistMultiply(*color_twist,effect,&result); 00658 *color_twist=result; 00659 } 00660 00661 static void SetColorBalance(double red,double green,double blue, 00662 FPXColorTwistMatrix *color_twist) 00663 { 00664 FPXColorTwistMatrix 00665 blue_effect, 00666 green_effect, 00667 result, 00668 rgb_effect, 00669 rg_effect, 00670 red_effect; 00671 00672 /* 00673 Set image color balance in color twist matrix. 00674 */ 00675 assert(color_twist != (FPXColorTwistMatrix *) NULL); 00676 red=sqrt((double) red)-1.0; 00677 green=sqrt((double) green)-1.0; 00678 blue=sqrt((double) blue)-1.0; 00679 red_effect.byy=1.0; 00680 red_effect.byc1=0.0; 00681 red_effect.byc2=0.299*red; 00682 red_effect.dummy1_zero=0.0; 00683 red_effect.bc1y=(-0.299)*red; 00684 red_effect.bc1c1=1.0-0.299*red; 00685 red_effect.bc1c2=(-0.299)*red; 00686 red_effect.dummy2_zero=0.0; 00687 red_effect.bc2y=0.701*red; 00688 red_effect.bc2c1=0.0; 00689 red_effect.bc2c2=1.0+0.402*red; 00690 red_effect.dummy3_zero=0.0; 00691 red_effect.dummy4_zero=0.0; 00692 red_effect.dummy5_zero=0.0; 00693 red_effect.dummy6_zero=0.0; 00694 red_effect.dummy7_one=1.0; 00695 green_effect.byy=1.0; 00696 green_effect.byc1=(-0.114)*green; 00697 green_effect.byc2=(-0.299)*green; 00698 green_effect.dummy1_zero=0.0; 00699 green_effect.bc1y=(-0.587)*green; 00700 green_effect.bc1c1=1.0-0.473*green; 00701 green_effect.bc1c2=0.299*green; 00702 green_effect.dummy2_zero=0.0; 00703 green_effect.bc2y=(-0.587)*green; 00704 green_effect.bc2c1=0.114*green; 00705 green_effect.bc2c2=1.0-0.288*green; 00706 green_effect.dummy3_zero=0.0; 00707 green_effect.dummy4_zero=0.0; 00708 green_effect.dummy5_zero=0.0; 00709 green_effect.dummy6_zero=0.0; 00710 green_effect.dummy7_one=1.0; 00711 blue_effect.byy=1.0; 00712 blue_effect.byc1=0.114*blue; 00713 blue_effect.byc2=0.0; 00714 blue_effect.dummy1_zero=0.0; 00715 blue_effect.bc1y=0.886*blue; 00716 blue_effect.bc1c1=1.0+0.772*blue; 00717 blue_effect.bc1c2=0.0; 00718 blue_effect.dummy2_zero=0.0; 00719 blue_effect.bc2y=(-0.114)*blue; 00720 blue_effect.bc2c1=(-0.114)*blue; 00721 blue_effect.bc2c2=1.0-0.114*blue; 00722 blue_effect.dummy3_zero=0.0; 00723 blue_effect.dummy4_zero=0.0; 00724 blue_effect.dummy5_zero=0.0; 00725 blue_effect.dummy6_zero=0.0; 00726 blue_effect.dummy7_one=1.0; 00727 ColorTwistMultiply(red_effect,green_effect,&rg_effect); 00728 ColorTwistMultiply(rg_effect,blue_effect,&rgb_effect); 00729 ColorTwistMultiply(*color_twist,rgb_effect,&result); 00730 *color_twist=result; 00731 } 00732 00733 static void SetSaturation(double saturation,FPXColorTwistMatrix *color_twist) 00734 { 00735 FPXColorTwistMatrix 00736 effect, 00737 result; 00738 00739 /* 00740 Set image saturation in color twist matrix. 00741 */ 00742 assert(color_twist != (FPXColorTwistMatrix *) NULL); 00743 effect.byy=1.0; 00744 effect.byc1=0.0; 00745 effect.byc2=0.0; 00746 effect.dummy1_zero=0.0; 00747 effect.bc1y=0.0; 00748 effect.bc1c1=saturation; 00749 effect.bc1c2=0.0; 00750 effect.dummy2_zero=0.0; 00751 effect.bc2y=0.0; 00752 effect.bc2c1=0.0; 00753 effect.bc2c2=saturation; 00754 effect.dummy3_zero=0.0; 00755 effect.dummy4_zero=0.0; 00756 effect.dummy5_zero=0.0; 00757 effect.dummy6_zero=0.0; 00758 effect.dummy7_one=1.0; 00759 ColorTwistMultiply(*color_twist,effect,&result); 00760 *color_twist=result; 00761 } 00762 00763 static MagickBooleanType WriteFPXImage(const ImageInfo *image_info,Image *image) 00764 { 00765 FPXBackground 00766 background_color; 00767 00768 FPXColorspace 00769 colorspace = 00770 { 00771 TRUE, 4, 00772 { 00773 { NIFRGB_R, DATA_TYPE_UNSIGNED_BYTE }, 00774 { NIFRGB_G, DATA_TYPE_UNSIGNED_BYTE }, 00775 { NIFRGB_B, DATA_TYPE_UNSIGNED_BYTE }, 00776 { ALPHA, DATA_TYPE_UNSIGNED_BYTE } 00777 } 00778 }; 00779 00780 const ImageAttribute 00781 *comment, 00782 *label; 00783 00784 FPXCompressionOption 00785 compression; 00786 00787 FPXImageDesc 00788 fpx_info; 00789 00790 FPXImageHandle 00791 *flashpix; 00792 00793 FPXStatus 00794 fpx_status; 00795 00796 FPXSummaryInformation 00797 summary_info; 00798 00799 long 00800 y; 00801 00802 MagickBooleanType 00803 status; 00804 00805 register const PixelPacket 00806 *p; 00807 00808 register long 00809 i; 00810 00811 unsigned char 00812 *pixels; 00813 00814 unsigned long 00815 memory_limit, 00816 tile_height, 00817 tile_width; 00818 00819 /* 00820 Open input file. 00821 */ 00822 assert(image_info != (const ImageInfo *) NULL); 00823 assert(image_info->signature == MagickSignature); 00824 assert(image != (Image *) NULL); 00825 assert(image->signature == MagickSignature); 00826 if (image->debug != MagickFalse) 00827 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 00828 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); 00829 if (status == MagickFalse) 00830 return(status); 00831 CloseBlob(image); 00832 /* 00833 Initialize FPX toolkit. 00834 */ 00835 image->depth=8; 00836 (void) SetImageColorspace(image,RGBColorspace); 00837 memory_limit=20000000; 00838 fpx_status=FPX_SetToolkitMemoryLimit(&memory_limit); 00839 if (fpx_status != FPX_OK) 00840 ThrowWriterException(DelegateError,"UnableToInitializeFPXLibrary"); 00841 tile_width=64; 00842 tile_height=64; 00843 colorspace.numberOfComponents=3; 00844 if (image->matte != MagickFalse) 00845 colorspace.numberOfComponents=4; 00846 if ((image_info->type != TrueColorType) && 00847 IsGrayImage(image,&image->exception)) 00848 { 00849 colorspace.numberOfComponents=1; 00850 colorspace.theComponents[0].myColor=MONOCHROME; 00851 } 00852 background_color.color1_value=0; 00853 background_color.color2_value=0; 00854 background_color.color3_value=0; 00855 background_color.color4_value=0; 00856 compression=NONE; 00857 if (image->compression == JPEGCompression) 00858 compression=JPEG_UNSPECIFIED; 00859 { 00860 #if defined(macintosh) 00861 FSSpec 00862 fsspec; 00863 00864 FilenameToFSSpec(filename,&fsspec); 00865 fpx_status=FPX_CreateImageByFilename((const FSSpec &) fsspec,image->columns, 00866 #else 00867 fpx_status=FPX_CreateImageByFilename(image->filename,image->columns, 00868 #endif 00869 image->rows,tile_width,tile_height,colorspace,background_color, 00870 compression,&flashpix); 00871 } 00872 if (fpx_status != FPX_OK) 00873 return(status); 00874 if (compression == JPEG_UNSPECIFIED) 00875 { 00876 /* 00877 Initialize the compression by quality for the entire image. 00878 */ 00879 fpx_status=FPX_SetJPEGCompression(flashpix,(unsigned short) 00880 image->quality == UndefinedCompressionQuality ? 75 : image->quality); 00881 if (fpx_status != FPX_OK) 00882 ThrowWriterException(DelegateError,"UnableToSetJPEGLevel"); 00883 } 00884 /* 00885 Set image summary info. 00886 */ 00887 summary_info.title_valid=MagickFalse; 00888 summary_info.subject_valid=MagickFalse; 00889 summary_info.author_valid=MagickFalse; 00890 summary_info.comments_valid=MagickFalse; 00891 summary_info.keywords_valid=MagickFalse; 00892 summary_info.OLEtemplate_valid=MagickFalse; 00893 summary_info.last_author_valid=MagickFalse; 00894 summary_info.rev_number_valid=MagickFalse; 00895 summary_info.edit_time_valid=MagickFalse; 00896 summary_info.last_printed_valid=MagickFalse; 00897 summary_info.create_dtm_valid=MagickFalse; 00898 summary_info.last_save_dtm_valid=MagickFalse; 00899 summary_info.page_count_valid=MagickFalse; 00900 summary_info.word_count_valid=MagickFalse; 00901 summary_info.char_count_valid=MagickFalse; 00902 summary_info.thumbnail_valid=MagickFalse; 00903 summary_info.appname_valid=MagickFalse; 00904 summary_info.security_valid=MagickFalse; 00905 label=GetImageAttribute(image,"label"); 00906 if (label != (ImageAttribute *) NULL) 00907 { 00908 /* 00909 Note image label. 00910 */ 00911 summary_info.title_valid=MagickTrue; 00912 summary_info.title.length=strlen(label->value); 00913 summary_info.title.ptr=(unsigned char *) 00914 AcquireMagickMemory(strlen(label->value)+MaxTextExtent); 00915 if (summary_info.title.ptr == (unsigned char *) NULL) 00916 ThrowWriterException(DelegateError,"UnableToSetImageTitle"); 00917 (void) CopyMagickString((char *) summary_info.title.ptr,label->value, 00918 MaxTextExtent); 00919 } 00920 comment=GetImageAttribute(image,"Comment"); 00921 if (comment != (ImageAttribute *) NULL) 00922 { 00923 /* 00924 Note image comment. 00925 */ 00926 summary_info.comments_valid=MagickTrue; 00927 summary_info.comments.length=strlen(comment->value); 00928 summary_info.comments.ptr=(unsigned char *) 00929 AcquireMagickMemory(strlen(comment->value)+MaxTextExtent); 00930 if (summary_info.comments.ptr == (unsigned char *) NULL) 00931 ThrowWriterException(DelegateError,"UnableToSetImageComment"); 00932 (void) strcpy((char *) summary_info.comments.ptr,comment->value); 00933 } 00934 fpx_status=FPX_SetSummaryInformation(flashpix,&summary_info); 00935 if (fpx_status != FPX_OK) 00936 ThrowWriterException(DelegateError,"UnableToSetSummaryInfo"); 00937 /* 00938 Allocate pixels. 00939 */ 00940 pixels=(unsigned char *) 00941 AcquireMagickMemory(colorspace.numberOfComponents*image->columns); 00942 if (pixels == (unsigned char *) NULL) 00943 { 00944 (void) FPX_CloseImage(flashpix); 00945 FPX_ClearSystem(); 00946 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); 00947 } 00948 /* 00949 Initialize FlashPix image description. 00950 */ 00951 fpx_info.numberOfComponents=colorspace.numberOfComponents; 00952 for (i=0; i < (long) fpx_info.numberOfComponents; i++) 00953 { 00954 fpx_info.components[i].myColorType.myDataType=DATA_TYPE_UNSIGNED_BYTE; 00955 fpx_info.components[i].horzSubSampFactor=1; 00956 fpx_info.components[i].vertSubSampFactor=1; 00957 fpx_info.components[i].columnStride=fpx_info.numberOfComponents; 00958 fpx_info.components[i].lineStride= 00959 image->columns*fpx_info.components[i].columnStride; 00960 fpx_info.components[i].theData=pixels+i; 00961 } 00962 fpx_info.components[0].myColorType.myColor= 00963 fpx_info.numberOfComponents != 1 ? NIFRGB_R : MONOCHROME; 00964 fpx_info.components[1].myColorType.myColor=NIFRGB_G; 00965 fpx_info.components[2].myColorType.myColor=NIFRGB_B; 00966 fpx_info.components[3].myColorType.myColor=ALPHA; 00967 /* 00968 Write image scanlines. 00969 */ 00970 for (y=0; y < (long) image->rows; y++) 00971 { 00972 p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception); 00973 if (p == (const PixelPacket *) NULL) 00974 break; 00975 if (fpx_info.numberOfComponents == 1) 00976 (void) PopImagePixels(image,GrayQuantum,pixels); 00977 else 00978 if (image->matte == MagickFalse) 00979 (void) PopImagePixels(image,RGBQuantum,pixels); 00980 else 00981 (void) PopImagePixels(image,RGBAQuantum,pixels); 00982 fpx_status=FPX_WriteImageLine(flashpix,&fpx_info); 00983 if (fpx_status != FPX_OK) 00984 break; 00985 if ((image->progress_monitor != (MagickProgressMonitor) NULL) && 00986 (QuantumTick(y,image->rows) != MagickFalse)) 00987 { 00988 status=image->progress_monitor(SaveImageTag,y,image->rows, 00989 image->client_data); 00990 if (status == MagickFalse) 00991 break; 00992 } 00993 } 00994 if (image_info->view != (char *) NULL) 00995 { 00996 FPXAffineMatrix 00997 affine; 00998 00999 FPXColorTwistMatrix 01000 color_twist; 01001 01002 FPXContrastAdjustment 01003 contrast; 01004 01005 FPXFilteringValue 01006 sharpen; 01007 01008 FPXResultAspectRatio 01009 aspect_ratio; 01010 01011 FPXROI 01012 view_rect; 01013 01014 MagickBooleanType 01015 affine_valid, 01016 aspect_ratio_valid, 01017 color_twist_valid, 01018 contrast_valid, 01019 sharpen_valid, 01020 view_rect_valid; 01021 01022 /* 01023 Initialize default viewing parameters. 01024 */ 01025 contrast=1.0; 01026 contrast_valid=MagickFalse; 01027 color_twist.byy=1.0; 01028 color_twist.byc1=0.0; 01029 color_twist.byc2=0.0; 01030 color_twist.dummy1_zero=0.0; 01031 color_twist.bc1y=0.0; 01032 color_twist.bc1c1=1.0; 01033 color_twist.bc1c2=0.0; 01034 color_twist.dummy2_zero=0.0; 01035 color_twist.bc2y=0.0; 01036 color_twist.bc2c1=0.0; 01037 color_twist.bc2c2=1.0; 01038 color_twist.dummy3_zero=0.0; 01039 color_twist.dummy4_zero=0.0; 01040 color_twist.dummy5_zero=0.0; 01041 color_twist.dummy6_zero=0.0; 01042 color_twist.dummy7_one=1.0; 01043 color_twist_valid=MagickFalse; 01044 sharpen=0.0; 01045 sharpen_valid=MagickFalse; 01046 aspect_ratio=(double) image->columns/image->rows; 01047 aspect_ratio_valid=MagickFalse; 01048 view_rect.left=(float) 0.1; 01049 view_rect.width=aspect_ratio-0.2; 01050 view_rect.top=(float) 0.1; 01051 view_rect.height=(float) 0.8; /* 1.0-0.2 */ 01052 view_rect_valid=MagickFalse; 01053 affine.a11=1.0; 01054 affine.a12=0.0; 01055 affine.a13=0.0; 01056 affine.a14=0.0; 01057 affine.a21=0.0; 01058 affine.a22=1.0; 01059 affine.a23=0.0; 01060 affine.a24=0.0; 01061 affine.a31=0.0; 01062 affine.a32=0.0; 01063 affine.a33=1.0; 01064 affine.a34=0.0; 01065 affine.a41=0.0; 01066 affine.a42=0.0; 01067 affine.a43=0.0; 01068 affine.a44=1.0; 01069 affine_valid=MagickFalse; 01070 if (0) 01071 { 01072 /* 01073 Color color twist. 01074 */ 01075 SetBrightness(0.5,&color_twist); 01076 SetSaturation(0.5,&color_twist); 01077 SetColorBalance(0.5,1.0,1.0,&color_twist); 01078 color_twist_valid=MagickTrue; 01079 } 01080 if (affine_valid) 01081 { 01082 fpx_status=FPX_SetImageAffineMatrix(flashpix,&affine); 01083 if (fpx_status != FPX_OK) 01084 ThrowWriterException(DelegateError,"UnableToSetAffineMatrix"); 01085 } 01086 if (aspect_ratio_valid) 01087 { 01088 fpx_status=FPX_SetImageResultAspectRatio(flashpix,&aspect_ratio); 01089 if (fpx_status != FPX_OK) 01090 ThrowWriterException(DelegateError,"UnableToSetAspectRatio"); 01091 } 01092 if (color_twist_valid) 01093 { 01094 fpx_status=FPX_SetImageColorTwistMatrix(flashpix,&color_twist); 01095 if (fpx_status != FPX_OK) 01096 ThrowWriterException(DelegateError,"UnableToSetColorTwist"); 01097 } 01098 if (contrast_valid) 01099 { 01100 fpx_status=FPX_SetImageContrastAdjustment(flashpix,&contrast); 01101 if (fpx_status != FPX_OK) 01102 ThrowWriterException(DelegateError,"UnableToSetContrast"); 01103 } 01104 if (sharpen_valid) 01105 { 01106 fpx_status=FPX_SetImageFilteringValue(flashpix,&sharpen); 01107 if (fpx_status != FPX_OK) 01108 ThrowWriterException(DelegateError,"UnableToSetFilteringValue"); 01109 } 01110 if (view_rect_valid) 01111 { 01112 fpx_status=FPX_SetImageROI(flashpix,&view_rect); 01113 if (fpx_status != FPX_OK) 01114 ThrowWriterException(DelegateError,"UnableToSetRegionOfInterest"); 01115 } 01116 } 01117 (void) FPX_CloseImage(flashpix); 01118 FPX_ClearSystem(); 01119 pixels=(unsigned char *) RelinquishMagickMemory(pixels); 01120 return(MagickTrue); 01121 } 01122 #endif

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