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/exception.h"
00047 #include "magick/exception-private.h"
00048 #include "magick/list.h"
00049 #include "magick/memory_.h"
00050 #include "magick/string_.h"
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 MagickExport void AppendImageToList(Image **images,const Image *image)
00078 {
00079 register Image
00080 *p,
00081 *q;
00082
00083 assert(images != (Image **) NULL);
00084 if (image == (Image *) NULL)
00085 return;
00086 assert(image->signature == MagickSignature);
00087 if (image->debug != MagickFalse)
00088 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00089 if ((*images) == (Image *) NULL)
00090 {
00091 *images=(Image *) image;
00092 return;
00093 }
00094 assert((*images)->signature == MagickSignature);
00095 p=GetLastImageInList(*images);
00096 q=GetFirstImageInList(image);
00097 p->next=q;
00098 q->previous=p;
00099 SyncImageList(*images);
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 MagickExport Image *CloneImageList(const Image *images,ExceptionInfo *exception)
00127 {
00128 Image
00129 *clone,
00130 *image;
00131
00132 register Image
00133 *p;
00134
00135 if (images == (Image *) NULL)
00136 return((Image *) NULL);
00137 assert(images->signature == MagickSignature);
00138 while (images->previous != (Image *) NULL)
00139 images=images->previous;
00140 image=(Image *) NULL;
00141 for (p=(Image *) NULL; images != (Image *) NULL; images=images->next)
00142 {
00143 clone=CloneImage(images,0,0,MagickTrue,exception);
00144 if (clone == (Image *) NULL)
00145 {
00146 if (image != (Image *) NULL)
00147 image=DestroyImageList(image);
00148 return((Image *) NULL);
00149 }
00150 if (image == (Image *) NULL)
00151 {
00152 image=clone;
00153 p=image;
00154 continue;
00155 }
00156 p->next=clone;
00157 clone->previous=p;
00158 p=p->next;
00159 }
00160 return(image);
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
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 MagickExport Image *CloneImages(const Image *images,const char *scenes,
00201 ExceptionInfo *exception)
00202 {
00203 char
00204 *p;
00205
00206 const Image
00207 *next;
00208
00209 Image
00210 *clone_images,
00211 *image;
00212
00213 long
00214 first,
00215 last,
00216 step;
00217
00218 register long
00219 i;
00220
00221 size_t
00222 length;
00223
00224 assert(images != (const Image *) NULL);
00225 assert(images->signature == MagickSignature);
00226 assert(scenes != (char *) NULL);
00227 if (images->debug != MagickFalse)
00228 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
00229 assert(exception != (ExceptionInfo *) NULL);
00230 assert(exception->signature == MagickSignature);
00231 clone_images=NewImageList();
00232 images=GetFirstImageInList(images);
00233 length=GetImageListLength(images);
00234 for (p=(char *) scenes; *p != '\0';)
00235 {
00236 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
00237 p++;
00238 first=strtol(p,&p,10);
00239 if (first < 0)
00240 first+=(long) length;
00241 last=first;
00242 while (isspace((int) ((unsigned char) *p)) != 0)
00243 p++;
00244 if (*p == '-')
00245 {
00246 last=strtol(p+1,&p,10);
00247 if (last < 0)
00248 last+=(long) length;
00249 }
00250 for (step=first > last ? -1 : 1; first != (last+step); first+=step)
00251 {
00252 i=0;
00253 for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
00254 {
00255 if (i == first)
00256 {
00257 image=CloneImage(next,0,0,MagickTrue,exception);
00258 if (image == (Image *) NULL)
00259 break;
00260 AppendImageToList(&clone_images,image);
00261 }
00262 i++;
00263 }
00264 }
00265 }
00266 return(GetFirstImageInList(clone_images));
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 MagickExport void DeleteImageFromList(Image **images)
00293 {
00294 Image
00295 *image;
00296
00297 image=RemoveImageFromList(images);
00298 if (image != (Image *) NULL)
00299 (void) DestroyImage(image);
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 MagickExport void DeleteImages(Image **images,const char *scenes,
00339 ExceptionInfo *exception)
00340 {
00341 char
00342 *p;
00343
00344 Image
00345 *image;
00346
00347 long
00348 first,
00349 last;
00350
00351 MagickBooleanType
00352 *delete_list;
00353
00354 register long
00355 i;
00356
00357 size_t
00358 length;
00359
00360 assert(images != (Image **) NULL);
00361 assert((*images)->signature == MagickSignature);
00362 assert(scenes != (char *) NULL);
00363 if ((*images)->debug != MagickFalse)
00364 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00365 (*images)->filename);
00366 assert(exception != (ExceptionInfo *) NULL);
00367 assert(exception->signature == MagickSignature);
00368 *images=GetFirstImageInList(*images);
00369 length=GetImageListLength(*images);
00370 delete_list=(MagickBooleanType *) AcquireQuantumMemory(length,
00371 sizeof(*delete_list));
00372 if (delete_list == (MagickBooleanType *) NULL)
00373 {
00374 (void) ThrowMagickException(exception,GetMagickModule(),
00375 ResourceLimitError,"MemoryAllocationFailed","`%s'",(*images)->filename);
00376 return;
00377 }
00378 image=(*images);
00379 for (i=0; i < (long) length; i++)
00380 delete_list[i]=MagickFalse;
00381
00382
00383
00384 for (p=(char *) scenes; *p != '\0';)
00385 {
00386 while ((isspace((int)*p) != 0) || (*p == ','))
00387 p++;
00388 first=strtol(p,&p,10);
00389 if (first < 0)
00390 first+=(long) length;
00391 last=first;
00392 while (isspace((int) ((unsigned char) *p)) != 0)
00393 p++;
00394 if (*p == '-')
00395 {
00396 last=strtol(p+1,&p,10);
00397 if (last < 0)
00398 last+=(long) length;
00399 }
00400 if (first > last)
00401 continue;
00402 for (i=first; i <= last; i++)
00403 if ((i >= 0) && (i < (long) length))
00404 delete_list[i]=MagickTrue;
00405 }
00406
00407
00408
00409 image=(*images);
00410 for (i=0; i < (long) length; i++)
00411 {
00412 *images=image;
00413 image=GetNextImageInList(image);
00414 if (delete_list[i] != MagickFalse)
00415 DeleteImageFromList(images);
00416
00417 }
00418 (void) RelinquishMagickMemory(delete_list);
00419 *images=GetFirstImageInList(*images);
00420 }
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 MagickExport Image *DestroyImageList(Image *images)
00445 {
00446 if (images == (Image *) NULL)
00447 return((Image *) NULL);
00448 assert(images->signature == MagickSignature);
00449 if (images->debug != MagickFalse)
00450 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
00451 while (images != (Image *) NULL)
00452 DeleteImageFromList(&images);
00453 return((Image *) NULL);
00454 }
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 MagickExport Image *GetFirstImageInList(const Image *images)
00479 {
00480 register const Image
00481 *p;
00482
00483 if (images == (Image *) NULL)
00484 return((Image *) NULL);
00485 assert(images->signature == MagickSignature);
00486 for (p=images; p->previous != (Image *) NULL; p=p->previous) ;
00487 return((Image *) p);
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
00513
00514 MagickExport Image *GetImageFromList(const Image *images,const long index)
00515 {
00516 long
00517 offset;
00518
00519 register const Image
00520 *p;
00521
00522 register long
00523 i;
00524
00525 size_t
00526 length;
00527
00528 if (images == (Image *) NULL)
00529 return((Image *) NULL);
00530 assert(images->signature == MagickSignature);
00531 if (images->debug != MagickFalse)
00532 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
00533 for (p=images; p->previous != (Image *) NULL; p=p->previous) ;
00534 length=GetImageListLength(images);
00535 for (offset=index; offset < 0; offset+=(long) length) ;
00536 for (i=0; p != (Image *) NULL; p=p->next)
00537 if (i++ == (long) (offset % length))
00538 break;
00539 if (p == (Image *) NULL)
00540 return((Image *) NULL);
00541 return((Image *) p);
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 MagickExport long GetImageIndexInList(const Image *images)
00567 {
00568 register long
00569 i;
00570
00571 if (images == (const Image *) NULL)
00572 return(-1);
00573 assert(images->signature == MagickSignature);
00574 for (i=0; images->previous != (Image *) NULL; i++)
00575 images=images->previous;
00576 return(i);
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 MagickExport unsigned long GetImageListLength(const Image *images)
00603 {
00604 register long
00605 i;
00606
00607 if (images == (Image *) NULL)
00608 return(0);
00609 assert(images->signature == MagickSignature);
00610 if (images->debug != MagickFalse)
00611 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
00612 while (images->previous != (Image *) NULL)
00613 images=images->previous;
00614 for (i=0; images != (Image *) NULL; images=images->next)
00615 i++;
00616 return((unsigned long) i);
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 MagickExport Image *GetLastImageInList(const Image *images)
00642 {
00643 register const Image
00644 *p;
00645
00646 if (images == (Image *) NULL)
00647 return((Image *) NULL);
00648 assert(images->signature == MagickSignature);
00649 for (p=images; p->next != (Image *) NULL; p=p->next) ;
00650 return((Image *) p);
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 MagickExport Image *GetNextImageInList(const Image *images)
00676 {
00677 if (images == (Image *) NULL)
00678 return((Image *) NULL);
00679 assert(images->signature == MagickSignature);
00680 if (images->debug != MagickFalse)
00681 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
00682 return(images->next);
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 MagickExport Image *GetPreviousImageInList(const Image *images)
00708 {
00709 if (images == (Image *) NULL)
00710 return((Image *) NULL);
00711 assert(images->signature == MagickSignature);
00712 return(images->previous);
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 MagickExport Image **ImageListToArray(const Image *images,
00746 ExceptionInfo *exception)
00747 {
00748 Image
00749 **group;
00750
00751 register long
00752 i;
00753
00754 if (images == (Image *) NULL)
00755 return((Image **) NULL);
00756 assert(images->signature == MagickSignature);
00757 if (images->debug != MagickFalse)
00758 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
00759 group=(Image **) AcquireQuantumMemory((size_t) GetImageListLength(images)+1UL,
00760 sizeof(*group));
00761 if (group == (Image **) NULL)
00762 {
00763 (void) ThrowMagickException(exception,GetMagickModule(),
00764 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
00765 return((Image **) NULL);
00766 }
00767 images=GetFirstImageInList(images);
00768 for (i=0; images != (Image *) NULL; images=images->next)
00769 group[i++]=(Image *) images;
00770 group[i]=(Image *) NULL;
00771 return(group);
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 void InsertImageInList(Image **images,Image *image)
00801 {
00802 Image
00803 *split;
00804
00805 assert(images != (Image **) NULL);
00806 assert(image != (Image *) NULL);
00807 assert(image->signature == MagickSignature);
00808 if (image->debug != MagickFalse)
00809 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00810 if ((*images) == (Image *) NULL)
00811 return;
00812 assert((*images)->signature == MagickSignature);
00813 split=SplitImageList(*images);
00814 AppendImageToList(images,image);
00815 AppendImageToList(images,split);
00816 }
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836 MagickExport Image *NewImageList(void)
00837 {
00838 return((Image *) NULL);
00839 }
00840
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 MagickExport void PrependImageToList(Image **images,Image *image)
00866 {
00867 AppendImageToList(&image,*images);
00868 }
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896 MagickExport Image *RemoveImageFromList(Image **images)
00897 {
00898 register Image
00899 *p;
00900
00901 assert(images != (Image **) NULL);
00902 if ((*images) == (Image *) NULL)
00903 return((Image *) NULL);
00904 assert((*images)->signature == MagickSignature);
00905 if ((*images)->debug != MagickFalse)
00906 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00907 (*images)->filename);
00908 p=(*images);
00909 if ((p->previous == (Image *) NULL) && (p->next == (Image *) NULL))
00910 *images=(Image *) NULL;
00911 else
00912 {
00913 if (p->previous != (Image *) NULL)
00914 {
00915 p->previous->next=p->next;
00916 *images=p->previous;
00917 }
00918 if (p->next != (Image *) NULL)
00919 {
00920 p->next->previous=p->previous;
00921 *images=p->next;
00922 }
00923 p->previous=(Image *) NULL;
00924 p->next=(Image *) NULL;
00925 }
00926 return(p);
00927 }
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955 MagickExport Image *RemoveFirstImageFromList(Image **images)
00956 {
00957 Image
00958 *image;
00959
00960 assert(images != (Image **) NULL);
00961 if ((*images) == (Image *) NULL)
00962 return((Image *) NULL);
00963 assert((*images)->signature == MagickSignature);
00964 if ((*images)->debug != MagickFalse)
00965 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00966 (*images)->filename);
00967 image=(*images);
00968 while (image->previous != (Image *) NULL)
00969 image=image->previous;
00970 if (image == *images)
00971 *images=(*images)->next;
00972 if (image->next != (Image *) NULL)
00973 {
00974 image->next->previous=(Image *) NULL;
00975 image->next=(Image *) NULL;
00976 }
00977 return(image);
00978 }
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006 MagickExport Image *RemoveLastImageFromList(Image **images)
01007 {
01008 Image
01009 *image;
01010
01011 assert(images != (Image **) NULL);
01012 if ((*images) == (Image *) NULL)
01013 return((Image *) NULL);
01014 assert((*images)->signature == MagickSignature);
01015 if ((*images)->debug != MagickFalse)
01016 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
01017 (*images)->filename);
01018 image=(*images);
01019 while (image->next != (Image *) NULL)
01020 image=image->next;
01021 if (image == *images)
01022 *images=(*images)->previous;
01023 if (image->previous != (Image *) NULL)
01024 {
01025 image->previous->next=(Image *) NULL;
01026 image->previous=(Image *) NULL;
01027 }
01028 return(image);
01029 }
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056 MagickExport void ReplaceImageInList(Image **images,Image *image)
01057 {
01058 assert(images != (Image **) NULL);
01059 assert(image != (Image *) NULL);
01060 assert(image->signature == MagickSignature);
01061 if (image->debug != MagickFalse)
01062 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
01063 if ((*images) == (Image *) NULL)
01064 return;
01065 assert((*images)->signature == MagickSignature);
01066 image->next=(*images)->next;
01067 if (image->next != (Image *) NULL)
01068 image->next->previous=image;
01069 image->previous=(*images)->previous;
01070 if (image->previous != (Image *) NULL)
01071 image->previous->next=image;
01072 (void) DestroyImage(*images);
01073 (*images)=image;
01074 }
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099 MagickExport void ReverseImageList(Image **images)
01100 {
01101 Image
01102 *next;
01103
01104 register Image
01105 *p;
01106
01107 assert(images != (Image **) NULL);
01108 if ((*images) == (Image *) NULL)
01109 return;
01110 assert((*images)->signature == MagickSignature);
01111 if ((*images)->debug != MagickFalse)
01112 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
01113 (*images)->filename);
01114 for (p=(*images); p->next != (Image *) NULL; p=p->next) ;
01115 *images=p;
01116 for ( ; p != (Image *) NULL; p=p->next)
01117 {
01118 next=p->next;
01119 p->next=p->previous;
01120 p->previous=next;
01121 }
01122 }
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152 MagickExport Image *SpliceImageIntoList(Image **images,
01153 const unsigned long length,const Image *splice)
01154 {
01155 Image
01156 *image,
01157 *split;
01158
01159 register unsigned long
01160 i;
01161
01162 assert(images != (Image **) NULL);
01163 assert(splice != (Image *) NULL);
01164 assert(splice->signature == MagickSignature);
01165 if ((*images) == (Image *) NULL)
01166 return((Image *) NULL);
01167 assert((*images)->signature == MagickSignature);
01168 if ((*images)->debug != MagickFalse)
01169 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
01170 (*images)->filename);
01171 split=SplitImageList(*images);
01172 AppendImageToList(images,splice);
01173 image=(Image *) NULL;
01174 for (i=0; (i < length) && (split != (Image *) NULL); i++)
01175 AppendImageToList(&image,RemoveImageFromList(&split));
01176 AppendImageToList(images,split);
01177 return(image);
01178 }
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203 MagickExport Image *SplitImageList(Image *images)
01204 {
01205 if ((images == (Image *) NULL) || (images->next == (Image *) NULL))
01206 return((Image *) NULL);
01207 images=images->next;
01208 images->previous->next=(Image *) NULL;
01209 images->previous=(Image *) NULL;
01210 return(images);
01211 }
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235 MagickExport void SyncImageList(Image *images)
01236 {
01237 register Image
01238 *p,
01239 *q;
01240
01241 if (images == (Image *) NULL)
01242 return;
01243 assert(images->signature == MagickSignature);
01244 for (p=images; p != (Image *) NULL; p=p->next)
01245 {
01246 for (q=p->next; q != (Image *) NULL; q=q->next)
01247 if (p->scene == q->scene)
01248 break;
01249 if (q != (Image *) NULL)
01250 break;
01251 }
01252 if (p == (Image *) NULL)
01253 return;
01254 for (p=images->next; p != (Image *) NULL; p=p->next)
01255 p->scene=p->previous->scene+1;
01256 }
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281 MagickExport Image *SyncNextImageInList(const Image *images)
01282 {
01283 if (images == (Image *) NULL)
01284 return((Image *) NULL);
01285 assert(images->signature == MagickSignature);
01286 if (images->next == (Image *) NULL)
01287 return((Image *) NULL);
01288 if (images->blob != images->next->blob)
01289 {
01290 DestroyBlob(images->next);
01291 images->next->blob=ReferenceBlob(images->blob);
01292 }
01293 images->next->endian=images->endian;
01294 return(images->next);
01295 }