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
00043 #include "magick/studio.h"
00044 #include "magick/blob.h"
00045 #include "magick/blob-private.h"
00046 #include "magick/cache.h"
00047 #include "magick/cache-private.h"
00048 #include "magick/color-private.h"
00049 #include "magick/composite-private.h"
00050 #include "magick/constitute.h"
00051 #include "magick/exception.h"
00052 #include "magick/exception-private.h"
00053 #include "magick/geometry.h"
00054 #include "magick/memory_.h"
00055 #include "magick/quantum.h"
00056 #include "magick/quantum-private.h"
00057 #include "magick/semaphore.h"
00058 #include "magick/stream.h"
00059 #include "magick/stream-private.h"
00060 #include "magick/string_.h"
00061
00062
00063
00064
00065 struct _StreamInfo
00066 {
00067 const ImageInfo
00068 *image_info;
00069
00070 const Image
00071 *image;
00072
00073 Image
00074 *stream;
00075
00076 QuantumInfo
00077 *quantum_info;
00078
00079 char
00080 *map;
00081
00082 StorageType
00083 storage_type;
00084
00085 unsigned char
00086 *pixels;
00087
00088 RectangleInfo
00089 extract_info;
00090
00091 long
00092 y;
00093
00094 ExceptionInfo
00095 *exception;
00096
00097 const void
00098 *client_data;
00099
00100 unsigned long
00101 signature;
00102 };
00103
00104
00105
00106
00107 #if defined(__cplusplus) || defined(c_plusplus)
00108 extern "C" {
00109 #endif
00110
00111 static MagickBooleanType
00112 GetOneVirtualPixelFromStream(const Image *,const VirtualPixelMethod,
00113 const long,const long,PixelPacket *,ExceptionInfo *),
00114 GetOneAuthenticPixelFromStream(Image *,const long,const long,PixelPacket *,
00115 ExceptionInfo *),
00116 StreamImagePixels(const StreamInfo *,const Image *,ExceptionInfo *),
00117 SyncPixelStream(Image *,ExceptionInfo *);
00118
00119 static const PixelPacket
00120 *AcquirePixelStream(const Image *,const VirtualPixelMethod,const long,
00121 const long,const unsigned long,const unsigned long,ExceptionInfo *);
00122
00123 static PixelPacket
00124 *GetPixelStream(Image *,const long,const long,const unsigned long,
00125 const unsigned long,ExceptionInfo *),
00126 *GetPixelsFromStream(const Image *),
00127 *SetPixelStream(Image *,const long,const long,const unsigned long,
00128 const unsigned long,ExceptionInfo *);
00129
00130 static void
00131 DestroyPixelStream(Image *);
00132
00133 #if defined(__cplusplus) || defined(c_plusplus)
00134 }
00135 #endif
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 static const IndexPacket *AcquireIndexesFromStream(const Image *image)
00164 {
00165 CacheInfo
00166 *cache_info;
00167
00168 assert(image != (Image *) NULL);
00169 assert(image->signature == MagickSignature);
00170 if (image->debug != MagickFalse)
00171 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00172 cache_info=(CacheInfo *) image->cache;
00173 assert(cache_info->signature == MagickSignature);
00174 return(cache_info->indexes);
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 static const PixelPacket *AcquirePixelsFromStream(const Image *image)
00204 {
00205 CacheInfo
00206 *cache_info;
00207
00208 assert(image != (Image *) NULL);
00209 assert(image->signature == MagickSignature);
00210 if (image->debug != MagickFalse)
00211 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00212 cache_info=(CacheInfo *) image->cache;
00213 assert(cache_info->signature == MagickSignature);
00214 return(cache_info->pixels);
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 static inline void AcquireStreamPixels(CacheInfo *cache_info)
00254 {
00255 assert(cache_info != (CacheInfo *) NULL);
00256 assert(cache_info->length == (MagickSizeType) ((size_t) cache_info->length));
00257 cache_info->mapped=MagickFalse;
00258 cache_info->pixels=(PixelPacket *) AcquireMagickMemory((size_t)
00259 cache_info->length);
00260 if (cache_info->pixels == (PixelPacket *) NULL)
00261 {
00262 cache_info->mapped=MagickTrue;
00263 cache_info->pixels=(PixelPacket *) MapBlob(-1,IOMode,0,(size_t)
00264 cache_info->length);
00265 }
00266 }
00267
00268 static const PixelPacket *AcquirePixelStream(const Image *image,
00269 const VirtualPixelMethod magick_unused(virtual_pixel_method),const long x,
00270 const long y,const unsigned long columns,const unsigned long rows,
00271 ExceptionInfo *exception)
00272 {
00273 CacheInfo
00274 *cache_info;
00275
00276 MagickSizeType
00277 number_pixels;
00278
00279 size_t
00280 length;
00281
00282
00283
00284
00285 assert(image != (const Image *) NULL);
00286 assert(image->signature == MagickSignature);
00287 if (image->debug != MagickFalse)
00288 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00289 if ((x < 0) || (y < 0) || ((x+(long) columns) > (long) image->columns) ||
00290 ((y+(long) rows) > (long) image->rows) || (columns == 0) || (rows == 0))
00291 {
00292 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
00293 "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
00294 return((PixelPacket *) NULL);
00295 }
00296 cache_info=(CacheInfo *) image->cache;
00297 assert(cache_info->signature == MagickSignature);
00298 if (cache_info->type == UndefinedCache)
00299 {
00300 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
00301 "PixelCacheIsNotOpen","`%s'",image->filename);
00302 return((PixelPacket *) NULL);
00303 }
00304
00305
00306
00307 number_pixels=(MagickSizeType) columns*rows;
00308 length=(size_t) number_pixels*sizeof(PixelPacket);
00309 if ((image->storage_class == PseudoClass) ||
00310 (image->colorspace == CMYKColorspace))
00311 length+=number_pixels*sizeof(IndexPacket);
00312 cache_info->length=length;
00313 AcquireStreamPixels(cache_info);
00314 if (cache_info->pixels == (void *) NULL)
00315 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00316 cache_info->length=(MagickSizeType) length;
00317 cache_info->indexes=(IndexPacket *) NULL;
00318 if ((image->storage_class == PseudoClass) ||
00319 (image->colorspace == CMYKColorspace))
00320 cache_info->indexes=(IndexPacket *) (cache_info->pixels+number_pixels);
00321 return(cache_info->pixels);
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 MagickExport StreamInfo *AcquireStreamInfo(const ImageInfo *image_info)
00347 {
00348 StreamInfo
00349 *stream_info;
00350
00351 stream_info=(StreamInfo *) AcquireMagickMemory(sizeof(*stream_info));
00352 if (stream_info == (StreamInfo *) NULL)
00353 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00354 (void) ResetMagickMemory(stream_info,0,sizeof(*stream_info));
00355 stream_info->pixels=(unsigned char *) AcquireMagickMemory(
00356 sizeof(*stream_info->pixels));
00357 if (stream_info->pixels == (unsigned char *) NULL)
00358 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00359 stream_info->map=ConstantString("RGB");
00360 stream_info->storage_type=CharPixel;
00361 stream_info->stream=AcquireImage(image_info);
00362 stream_info->signature=MagickSignature;
00363 return(stream_info);
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 static inline void RelinquishStreamPixels(CacheInfo *cache_info)
00390 {
00391 assert(cache_info != (CacheInfo *) NULL);
00392 if (cache_info->mapped == MagickFalse)
00393 (void) RelinquishMagickMemory(cache_info->pixels);
00394 else
00395 (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
00396 cache_info->pixels=(PixelPacket *) NULL;
00397 cache_info->indexes=(IndexPacket *) NULL;
00398 }
00399
00400 static void DestroyPixelStream(Image *image)
00401 {
00402 CacheInfo
00403 *cache_info;
00404
00405 MagickBooleanType
00406 destroy;
00407
00408 assert(image != (Image *) NULL);
00409 assert(image->signature == MagickSignature);
00410 if (image->debug != MagickFalse)
00411 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00412 cache_info=(CacheInfo *) image->cache;
00413 assert(cache_info->signature == MagickSignature);
00414 destroy=MagickFalse;
00415 (void) LockSemaphoreInfo(cache_info->semaphore);
00416 cache_info->reference_count--;
00417 if (cache_info->reference_count == 0)
00418 destroy=MagickTrue;
00419 (void) UnlockSemaphoreInfo(cache_info->semaphore);
00420 if (destroy == MagickFalse)
00421 return;
00422 RelinquishStreamPixels(cache_info);
00423 if (cache_info->nexus_info != (NexusInfo **) NULL)
00424 cache_info->nexus_info=DestroyNexusInfo(cache_info->nexus_info,
00425 cache_info->number_threads);
00426 if (cache_info->disk_semaphore != (SemaphoreInfo *) NULL)
00427 DestroySemaphoreInfo(&cache_info->disk_semaphore);
00428 if (cache_info->nexus_semaphore != (SemaphoreInfo *) NULL)
00429 DestroySemaphoreInfo(&cache_info->nexus_semaphore);
00430 if (cache_info->semaphore != (SemaphoreInfo *) NULL)
00431 DestroySemaphoreInfo(&cache_info->semaphore);
00432 cache_info=(CacheInfo *) RelinquishMagickMemory(cache_info);
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 MagickExport StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
00459 {
00460 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00461 assert(stream_info != (StreamInfo *) NULL);
00462 assert(stream_info->signature == MagickSignature);
00463 if (stream_info->map != (char *) NULL)
00464 stream_info->map=DestroyString(stream_info->map);
00465 if (stream_info->pixels != (unsigned char *) NULL)
00466 stream_info->pixels=(unsigned char *) RelinquishMagickMemory(
00467 stream_info->pixels);
00468 if (stream_info->stream != (Image *) NULL)
00469 {
00470 (void) CloseBlob(stream_info->stream);
00471 stream_info->stream=DestroyImage(stream_info->stream);
00472 }
00473 if (stream_info->quantum_info != (QuantumInfo *) NULL)
00474 stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
00475 stream_info->signature=(~MagickSignature);
00476 stream_info=(StreamInfo *) RelinquishMagickMemory(stream_info);
00477 return(stream_info);
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 static IndexPacket *GetIndexesFromStream(const Image *image)
00507 {
00508 CacheInfo
00509 *cache_info;
00510
00511 assert(image != (Image *) NULL);
00512 assert(image->signature == MagickSignature);
00513 if (image->debug != MagickFalse)
00514 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00515 cache_info=(CacheInfo *) image->cache;
00516 assert(cache_info->signature == MagickSignature);
00517 return(cache_info->indexes);
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 static MagickBooleanType GetOneVirtualPixelFromStream(const Image *image,
00554 const VirtualPixelMethod virtual_pixel_method,const long x,const long y,
00555 PixelPacket *pixel,ExceptionInfo *exception)
00556 {
00557 const PixelPacket
00558 *pixels;
00559
00560 assert(image != (Image *) NULL);
00561 assert(image->signature == MagickSignature);
00562 *pixel=image->background_color;
00563 pixels=AcquirePixelStream(image,virtual_pixel_method,x,y,1,1,exception);
00564 if (pixels != (const PixelPacket *) NULL)
00565 return(MagickFalse);
00566 *pixel=(*pixels);
00567 return(MagickTrue);
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,const long x,
00601 const long y,PixelPacket *pixel,ExceptionInfo *exception)
00602 {
00603 register PixelPacket
00604 *pixels;
00605
00606 assert(image != (Image *) NULL);
00607 assert(image->signature == MagickSignature);
00608 *pixel=image->background_color;
00609 pixels=GetPixelStream(image,x,y,1,1,exception);
00610 if (pixels != (PixelPacket *) NULL)
00611 return(MagickFalse);
00612 *pixel=(*pixels);
00613 return(MagickTrue);
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648 static PixelPacket *GetPixelStream(Image *image,const long x,const long y,
00649 const unsigned long columns,const unsigned long rows,ExceptionInfo *exception)
00650 {
00651 PixelPacket
00652 *pixels;
00653
00654 assert(image != (Image *) NULL);
00655 assert(image->signature == MagickSignature);
00656 if (image->debug != MagickFalse)
00657 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00658 pixels=SetPixelStream(image,x,y,columns,rows,exception);
00659 return(pixels);
00660 }
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 static PixelPacket *GetPixelsFromStream(const Image *image)
00689 {
00690 CacheInfo
00691 *cache_info;
00692
00693 assert(image != (Image *) NULL);
00694 assert(image->signature == MagickSignature);
00695 if (image->debug != MagickFalse)
00696 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00697 cache_info=(CacheInfo *) image->cache;
00698 assert(cache_info->signature == MagickSignature);
00699 return(cache_info->pixels);
00700 }
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 MagickExport const void *GetStreamInfoClientData(StreamInfo *stream_info)
00725 {
00726 assert(stream_info != (StreamInfo *) NULL);
00727 assert(stream_info->signature == MagickSignature);
00728 return(stream_info->client_data);
00729 }
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760 MagickExport MagickBooleanType OpenStream(const ImageInfo *image_info,
00761 StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
00762 {
00763 MagickBooleanType
00764 status;
00765
00766 (void) CopyMagickString(stream_info->stream->filename,filename,MaxTextExtent);
00767 status=OpenBlob(image_info,stream_info->stream,WriteBinaryBlobMode,exception);
00768 return(status);
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
00801 ExceptionInfo *exception)
00802 {
00803 CacheMethods
00804 cache_methods;
00805
00806 Image
00807 *image;
00808
00809 ImageInfo
00810 *read_info;
00811
00812
00813
00814
00815 assert(image_info != (ImageInfo *) NULL);
00816 assert(image_info->signature == MagickSignature);
00817 if (image_info->debug != MagickFalse)
00818 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00819 image_info->filename);
00820 assert(exception != (ExceptionInfo *) NULL);
00821 assert(exception->signature == MagickSignature);
00822 read_info=CloneImageInfo(image_info);
00823 (void) GetCacheInfo(&read_info->cache,0);
00824 GetCacheMethods(&cache_methods);
00825 cache_methods.acquire_pixel_handler=AcquirePixelStream;
00826 cache_methods.acquire_indexes_from_handler=AcquireIndexesFromStream;
00827 cache_methods.acquire_pixels_from_handler=AcquirePixelsFromStream;
00828 cache_methods.get_pixel_handler=GetPixelStream;
00829 cache_methods.set_pixel_handler=SetPixelStream;
00830 cache_methods.sync_pixel_handler=SyncPixelStream;
00831 cache_methods.get_pixels_from_handler=GetPixelsFromStream;
00832 cache_methods.get_indexes_from_handler=GetIndexesFromStream;
00833 cache_methods.acquire_one_pixel_from_handler=GetOneVirtualPixelFromStream;
00834 cache_methods.get_one_pixel_from_handler=GetOneAuthenticPixelFromStream;
00835 cache_methods.destroy_pixel_handler=DestroyPixelStream;
00836 SetCacheMethods(read_info->cache,&cache_methods);
00837 read_info->stream=stream;
00838 image=ReadImage(read_info,exception);
00839 read_info=DestroyImageInfo(read_info);
00840 return(image);
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874 static PixelPacket *SetPixelStream(Image *image,const long x,const long y,
00875 const unsigned long columns,const unsigned long rows,ExceptionInfo *exception)
00876 {
00877 CacheInfo
00878 *cache_info;
00879
00880 MagickSizeType
00881 number_pixels;
00882
00883 size_t
00884 length;
00885
00886 StreamHandler
00887 stream_handler;
00888
00889
00890
00891
00892 assert(image != (Image *) NULL);
00893 if ((x < 0) || (y < 0) || ((x+(long) columns) > (long) image->columns) ||
00894 ((y+(long) rows) > (long) image->rows) || (columns == 0) || (rows == 0))
00895 {
00896 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
00897 "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
00898 return((PixelPacket *) NULL);
00899 }
00900 stream_handler=GetBlobStreamHandler(image);
00901 if (stream_handler == (StreamHandler) NULL)
00902 {
00903 (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
00904 "NoStreamHandlerIsDefined","`%s'",image->filename);
00905 return((PixelPacket *) NULL);
00906 }
00907 cache_info=(CacheInfo *) image->cache;
00908 assert(cache_info->signature == MagickSignature);
00909 if ((image->storage_class != GetCacheClass(image->cache)) ||
00910 (image->colorspace != GetCacheColorspace(image->cache)))
00911 {
00912 if (GetCacheClass(image->cache) == UndefinedClass)
00913 (void) stream_handler(image,(const void *) NULL,(size_t)
00914 cache_info->columns);
00915 cache_info->storage_class=image->storage_class;
00916 cache_info->colorspace=image->colorspace;
00917 cache_info->columns=image->columns;
00918 cache_info->rows=image->rows;
00919 image->cache=cache_info;
00920 }
00921
00922
00923
00924 cache_info->columns=columns;
00925 cache_info->rows=rows;
00926 number_pixels=(MagickSizeType) columns*rows;
00927 length=(size_t) number_pixels*sizeof(PixelPacket);
00928 if ((image->storage_class == PseudoClass) ||
00929 (image->colorspace == CMYKColorspace))
00930 length+=number_pixels*sizeof(IndexPacket);
00931 if (cache_info->pixels == (PixelPacket *) NULL)
00932 {
00933 cache_info->pixels=(PixelPacket *) AcquireMagickMemory(length);
00934 cache_info->length=(MagickSizeType) length;
00935 }
00936 else
00937 if (cache_info->length < (MagickSizeType) length)
00938 {
00939 cache_info->pixels=(PixelPacket *) ResizeMagickMemory(
00940 cache_info->pixels,length);
00941 cache_info->length=(MagickSizeType) length;
00942 }
00943 if (cache_info->pixels == (void *) NULL)
00944 ThrowFatalException(ResourceLimitFatalError,
00945 "UnableToGetVirtualPixels");
00946 cache_info->indexes=(IndexPacket *) NULL;
00947 if ((image->storage_class == PseudoClass) ||
00948 (image->colorspace == CMYKColorspace))
00949 cache_info->indexes=(IndexPacket *) (cache_info->pixels+number_pixels);
00950 return(cache_info->pixels);
00951 }
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961