00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
00072
00073
static MagickBooleanType
00074 WriteFPXImage(
const ImageInfo *,
Image *);
00075
#endif
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
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
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
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
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
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
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
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
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
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
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
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
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
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
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
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
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
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
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 ModuleExport void UnregisterFPXImage(
void)
00550 {
00551 (
void)
UnregisterMagickInfo(
"FPX");
00552 }
00553
00554
#if defined(HasFPX)
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
static void ColorTwistMultiply(FPXColorTwistMatrix first,
00583 FPXColorTwistMatrix second,FPXColorTwistMatrix *color_twist)
00584 {
00585
00586
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
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
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
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
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
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
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
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
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
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
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
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
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
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;
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
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