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

Go to the documentation of this file.
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % M M EEEEE TTTTT AAA % 00007 % MM MM E T A A % 00008 % M M M EEE T AAAAA % 00009 % M M E T A A % 00010 % M M EEEEE T A A % 00011 % % 00012 % % 00013 % Read/Write Embedded Image Profiles. % 00014 % % 00015 % Software Design % 00016 % William Radcliffe % 00017 % July 2001 % 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/blob.h" 00044 #include "magick/blob_private.h" 00045 #include "magick/error.h" 00046 #include "magick/error_private.h" 00047 #include "magick/image.h" 00048 #include "magick/image_private.h" 00049 #include "magick/list.h" 00050 #include "magick/magick.h" 00051 #include "magick/memory_.h" 00052 #include "magick/profile.h" 00053 #include "magick/static.h" 00054 #include "magick/string_.h" 00055 #include "magick/token.h" 00056 #include "magick/utility.h" 00057 00058 /* 00059 Forward declarations. 00060 */ 00061 static MagickBooleanType 00062 WriteMETAImage(const ImageInfo *,Image *); 00063 00064 /* 00065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00066 % % 00067 % % 00068 % % 00069 % I s M E T A % 00070 % % 00071 % % 00072 % % 00073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00074 % 00075 % IsMETA() returns MagickTrue if the image format type, identified by the 00076 % magick string, is META. 00077 % 00078 % The format of the IsMETA method is: 00079 % 00080 % MagickBooleanType IsMETA(const unsigned char *magick,const size_t length) 00081 % 00082 % A description of each parameter follows: 00083 % 00084 % o magick: This string is generally the first few bytes of an image file 00085 % or blob. 00086 % 00087 % o length: Specifies the length of the magick string. 00088 % 00089 % 00090 */ 00091 #ifdef IMPLEMENT_IS_FUNCTION 00092 static MagickBooleanType IsMETA(const unsigned char *magick,const size_t length) 00093 { 00094 if (length < 4) 00095 return(MagickFalse); 00096 if (LocaleNCompare((char *) magick,"8BIM",4) == 0) 00097 return(MagickTrue); 00098 if (LocaleNCompare((char *) magick,"APP1",4) == 0) 00099 return(MagickTrue); 00100 if (LocaleNCompare((char *) magick,"\034\002",2) == 0) 00101 return(MagickTrue); 00102 return(MagickFalse); 00103 } 00104 #endif 00105 00106 /* 00107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00108 % % 00109 % % 00110 % % 00111 % R e a d M E T A I m a g e % 00112 % % 00113 % % 00114 % % 00115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00116 % 00117 % ReadMETAImage() reads a META image file and returns it. It 00118 % allocates the memory necessary for the new Image structure and returns a 00119 % pointer to the new image. 00120 % 00121 % The format of the ReadMETAImage method is: 00122 % 00123 % Image *ReadMETAImage(const ImageInfo *image_info, 00124 % ExceptionInfo *exception) 00125 % 00126 % Decompression code contributed by Kyle Shorter. 00127 % 00128 % A description of each parameter follows: 00129 % 00130 % o image: Method ReadMETAImage returns a pointer to the image after 00131 % reading. A null image is returned if there is a memory shortage or 00132 % if the image cannot be read. 00133 % 00134 % o image_info: Specifies a pointer to an ImageInfo structure. 00135 % 00136 % o exception: return any errors or warnings in this structure. 00137 % 00138 % 00139 */ 00140 #define BUFFER_SZ 4096 00141 00142 typedef struct _html_code 00143 { 00144 short 00145 len; 00146 const char 00147 *code, 00148 val; 00149 } html_code; 00150 00151 static html_code html_codes[] = { 00152 #ifdef HANDLE_GT_LT 00153 { 4,"&lt;",'<' }, 00154 { 4,"&gt;",'>' }, 00155 #endif 00156 { 5,"&amp;",'&' }, 00157 { 6,"&quot;",'"' }, 00158 { 6,"&apos;",'\''} 00159 }; 00160 00161 static int stringnicmp(const char *p,const char *q,size_t n) 00162 { 00163 register long 00164 i, 00165 j; 00166 00167 if (p == q) 00168 return(0); 00169 if (p == (char *) NULL) 00170 return(-1); 00171 if (q == (char *) NULL) 00172 return(1); 00173 while ((*p != '\0') && (*q != '\0')) 00174 { 00175 if ((*p == '\0') || (*q == '\0')) 00176 break; 00177 i=(*p); 00178 if (islower(i)) 00179 i=toupper(i); 00180 j=(*q); 00181 if (islower(j)) 00182 j=toupper(j); 00183 if (i != j) 00184 break; 00185 n--; 00186 if (n == 0) 00187 break; 00188 p++; 00189 q++; 00190 } 00191 return(toupper(*p)-toupper(*q)); 00192 } 00193 00194 static int convertHTMLcodes(char *s, int len) 00195 { 00196 if (len <=0 || s==(char*)NULL || *s=='\0') 00197 return 0; 00198 00199 if (s[1] == '#') 00200 { 00201 int val, o; 00202 00203 if (sscanf(s,"&#%d;",&val) == 1) 00204 { 00205 o = 3; 00206 while (s[o] != ';') 00207 { 00208 o++; 00209 if (o > 5) 00210 break; 00211 } 00212 if (o < 6) 00213 (void) strcpy(s+1, s+1+o); 00214 *s = val; 00215 return o; 00216 } 00217 } 00218 else 00219 { 00220 int 00221 i, 00222 codes = sizeof(html_codes) / sizeof(html_code); 00223 00224 for (i=0; i < codes; i++) 00225 { 00226 if (html_codes[i].len <= len) 00227 if (stringnicmp(s, html_codes[i].code, html_codes[i].len) == 0) 00228 { 00229 (void) strcpy(s+1, s+html_codes[i].len); 00230 *s = html_codes[i].val; 00231 return html_codes[i].len-1; 00232 } 00233 } 00234 } 00235 return 0; 00236 } 00237 00238 static char *super_fgets(char **b, int *blen, Image *file) 00239 { 00240 int 00241 c, 00242 len; 00243 00244 unsigned char 00245 *p, 00246 *q; 00247 00248 len=*blen; 00249 p=(unsigned char *) (*b); 00250 for (q=p; ; q++) 00251 { 00252 c=ReadBlobByte(file); 00253 if (c == EOF || c == '\n') 00254 break; 00255 if ((q-p+1) >= (int) len) 00256 { 00257 int 00258 tlen; 00259 00260 tlen=q-p; 00261 len<<=1; 00262 p=(unsigned char *) ResizeMagickMemory(p,(len+2)); 00263 *b=(char *) p; 00264 if (p == (unsigned char *) NULL) 00265 break; 00266 q=p+tlen; 00267 } 00268 *q=(unsigned char) c; 00269 } 00270 *blen=0; 00271 if (p != (unsigned char *) NULL) 00272 { 00273 int 00274 tlen; 00275 00276 tlen=q-p; 00277 if (tlen == 0) 00278 return (char *) NULL; 00279 p[tlen] = '\0'; 00280 *blen=++tlen; 00281 } 00282 return((char *) p); 00283 } 00284 00285 #define BUFFER_SZ 4096 00286 #define IPTC_ID 1028 00287 #define THUMBNAIL_ID 1033 00288 00289 static long parse8BIM(Image *ifile, Image *ofile) 00290 { 00291 char 00292 brkused, 00293 quoted, 00294 *line, 00295 *token, 00296 *newstr, 00297 *name; 00298 00299 int 00300 state, 00301 next; 00302 00303 unsigned char 00304 dataset; 00305 00306 unsigned int 00307 recnum; 00308 00309 int 00310 inputlen = BUFFER_SZ; 00311 00312 long 00313 savedolen = 0L, 00314 outputlen = 0L; 00315 00316 MagickOffsetType 00317 savedpos, 00318 currentpos; 00319 00320 TokenInfo 00321 token_info; 00322 00323 dataset = 0; 00324 recnum = 0; 00325 line = (char *) AcquireMagickMemory(inputlen); 00326 name = token = (char *)NULL; 00327 savedpos = 0; 00328 while(super_fgets(&line,&inputlen,ifile)!=NULL) 00329 { 00330 state=0; 00331 next=0; 00332 00333 token = (char *) AcquireMagickMemory(inputlen); 00334 newstr = (char *) AcquireMagickMemory(inputlen); 00335 while (Tokenizer(&token_info, 0, token, inputlen, line, 00336 (char *) "", (char *) "=", 00337 (char *) "\"", 0, &brkused,&next,&quoted)==0) 00338 { 00339 if (state == 0) 00340 { 00341 int 00342 state, 00343 next; 00344 00345 char 00346 brkused, 00347 quoted; 00348 00349 state=0; 00350 next=0; 00351 while(Tokenizer(&token_info, 0, newstr, inputlen, token, (char *) "", 00352 (char *) "#", (char *) "", 0, &brkused, &next, &quoted)==0) 00353 { 00354 switch (state) 00355 { 00356 case 0: 00357 if (strcmp(newstr,"8BIM")==0) 00358 dataset = 255; 00359 else 00360 dataset = (unsigned char) atoi(newstr); 00361 break; 00362 case 1: 00363 recnum = atoi(newstr); 00364 break; 00365 case 2: 00366 name=(char *) AcquireMagickMemory(strlen(newstr)+MaxTextExtent); 00367 if (name) 00368 (void) strcpy(name,newstr); 00369 break; 00370 } 00371 state++; 00372 } 00373 } 00374 else 00375 if (state == 1) 00376 { 00377 int 00378 next; 00379 00380 unsigned long 00381 len; 00382 00383 char 00384 brkused, 00385 quoted; 00386 00387 next=0; 00388 len = strlen(token); 00389 while (Tokenizer(&token_info,0, newstr, inputlen, token, (char *) "", 00390 (char *) "&", (char *) "", 0, &brkused, &next, &quoted)==0) 00391 { 00392 if (brkused && next > 0) 00393 { 00394 char 00395 *s = &token[next-1]; 00396 00397 len -= convertHTMLcodes(s, strlen(s)); 00398 } 00399 } 00400 00401 if (dataset == 255) 00402 { 00403 unsigned char 00404 nlen = 0; 00405 00406 int 00407 i; 00408 00409 if (savedolen > 0) 00410 { 00411 long diff = outputlen - savedolen; 00412 currentpos = TellBlob(ofile); 00413 SeekBlob(ofile,savedpos,SEEK_SET); 00414 WriteBlobMSBLong(ofile,diff); 00415 SeekBlob(ofile,currentpos,SEEK_SET); 00416 savedolen = 0L; 00417 } 00418 if (outputlen & 1) 00419 { 00420 WriteBlobByte(ofile,0x00); 00421 outputlen++; 00422 } 00423 WriteBlobString(ofile,"8BIM"); 00424 WriteBlobMSBShort(ofile,recnum); 00425 outputlen += 6; 00426 if (name) 00427 nlen = strlen(name); 00428 WriteBlobByte(ofile,nlen); 00429 outputlen++; 00430 for (i=0; i<nlen; i++) 00431 WriteBlobByte(ofile,name[i]); 00432 outputlen += nlen; 00433 if ((nlen & 0x01) == 0) 00434 { 00435 WriteBlobByte(ofile,0x00); 00436 outputlen++; 00437 } 00438 if (recnum != IPTC_ID) 00439 { 00440 WriteBlobMSBLong(ofile, len); 00441 outputlen += 4; 00442 00443 next=0; 00444 outputlen += len; 00445 while (len--) 00446 WriteBlobByte(ofile,token[next++]); 00447 00448 if (outputlen & 1) 00449 { 00450 WriteBlobByte(ofile,0x00); 00451 outputlen++; 00452 } 00453 } 00454 else 00455 { 00456 /* patch in a fake length for now and fix it later */ 00457 savedpos = TellBlob(ofile); 00458 WriteBlobMSBLong(ofile,0xFFFFFFFFUL); 00459 outputlen += 4; 00460 savedolen = outputlen; 00461 } 00462 } 00463 else 00464 { 00465 if (len <= 0x7FFF) 00466 { 00467 WriteBlobByte(ofile,0x1c); 00468 WriteBlobByte(ofile,dataset); 00469 WriteBlobByte(ofile,recnum & 255); 00470 WriteBlobMSBShort(ofile,len); 00471 outputlen += 5; 00472 next=0; 00473 outputlen += len; 00474 while (len--) 00475 WriteBlobByte(ofile,token[next++]); 00476 } 00477 } 00478 } 00479 state++; 00480 } 00481 token=(char *) RelinquishMagickMemory(token); 00482 newstr=(char *) RelinquishMagickMemory(newstr); 00483 name=(char *) RelinquishMagickMemory(name); 00484 } 00485 line=(char *) RelinquishMagickMemory(line); 00486 if (savedolen > 0) 00487 { 00488 long diff = outputlen - savedolen; 00489 00490 currentpos = TellBlob(ofile); 00491 SeekBlob(ofile,savedpos,SEEK_SET); 00492 WriteBlobMSBLong(ofile,diff); 00493 SeekBlob(ofile,currentpos,SEEK_SET); 00494 savedolen = 0L; 00495 } 00496 return outputlen; 00497 } 00498 00499 static char *super_fgets_w(char **b, int *blen, Image *file) 00500 { 00501 int 00502 c, 00503 len; 00504 00505 unsigned char 00506 *p, 00507 *q; 00508 00509 len=*blen; 00510 p=(unsigned char *) (*b); 00511 for (q=p; ; q++) 00512 { 00513 c=ReadBlobLSBShort(file); 00514 if (c == ((unsigned short) ~0) || c == '\n') 00515 break; 00516 if (EOFBlob(file)) 00517 break; 00518 if ((q-p+1) >= (int) len) 00519 { 00520 int 00521 tlen; 00522 00523 tlen=q-p; 00524 len<<=1; 00525 p=(unsigned char *) ResizeMagickMemory(p,(len+2)); 00526 *b=(char *) p; 00527 if (p == (unsigned char *) NULL) 00528 break; 00529 q=p+tlen; 00530 } 00531 *q=(unsigned char) c; 00532 } 00533 *blen=0; 00534 if ((*b) != (char *) NULL) 00535 { 00536 int 00537 tlen; 00538 00539 tlen=q-p; 00540 if (tlen == 0) 00541 return (char *) NULL; 00542 p[tlen] = '\0'; 00543 *blen=++tlen; 00544 } 00545 return((char *) p); 00546 } 00547 00548 static long parse8BIMW(Image *ifile, Image *ofile) 00549 { 00550 char 00551 brkused, 00552 quoted, 00553 *line, 00554 *token, 00555 *newstr, 00556 *name; 00557 00558 int 00559 state, 00560 next; 00561 00562 unsigned char 00563 dataset; 00564 00565 unsigned int 00566 recnum; 00567 00568 int 00569 inputlen = BUFFER_SZ; 00570 00571 long 00572 savedolen = 0L, 00573 outputlen = 0L; 00574 00575 MagickOffsetType 00576 savedpos, 00577 currentpos; 00578 00579 TokenInfo 00580 token_info; 00581 00582 dataset = 0; 00583 recnum = 0; 00584 line = (char *) AcquireMagickMemory(inputlen); 00585 name = token = (char *)NULL; 00586 savedpos = 0; 00587 while(super_fgets_w(&line,&inputlen,ifile)!=NULL) 00588 { 00589 state=0; 00590 next=0; 00591 00592 token = (char *) AcquireMagickMemory(inputlen); 00593 newstr = (char *) AcquireMagickMemory(inputlen); 00594 while (Tokenizer(&token_info, 0, token, inputlen, line, 00595 (char *) "", (char *) "=", 00596 (char *) "\"", 0, &brkused,&next,&quoted)==0) 00597 { 00598 if (state == 0) 00599 { 00600 int 00601 state, 00602 next; 00603 00604 char 00605 brkused, 00606 quoted; 00607 00608 state=0; 00609 next=0; 00610 while(Tokenizer(&token_info, 0, newstr, inputlen, token, (char *) "", 00611 (char *) "#", (char *) "", 0, &brkused, &next, &quoted)==0) 00612 { 00613 switch (state) 00614 { 00615 case 0: 00616 if (strcmp(newstr,"8BIM")==0) 00617 dataset = 255; 00618 else 00619 dataset = (unsigned char) atoi(newstr); 00620 break; 00621 case 1: 00622 recnum = atoi(newstr); 00623 break; 00624 case 2: 00625 name=(char *) AcquireMagickMemory(strlen(newstr)+MaxTextExtent); 00626 if (name) 00627 (void) strcpy(name,newstr); 00628 break; 00629 } 00630 state++; 00631 } 00632 } 00633 else 00634 if (state == 1) 00635 { 00636 int 00637 next; 00638 00639 unsigned long 00640 len; 00641 00642 char 00643 brkused, 00644 quoted; 00645 00646 next=0; 00647 len = strlen(token); 00648 while (Tokenizer(&token_info,0, newstr, inputlen, token, (char *) "", 00649 (char *) "&", (char *) "", 0, &brkused, &next, &quoted)==0) 00650 { 00651 if (brkused && next > 0) 00652 { 00653 char 00654 *s = &token[next-1]; 00655 00656 len -= convertHTMLcodes(s, strlen(s)); 00657 } 00658 } 00659 00660 if (dataset == 255) 00661 { 00662 unsigned char 00663 nlen = 0; 00664 00665 int 00666 i; 00667 00668 if (savedolen > 0) 00669 { 00670 long diff = outputlen - savedolen; 00671 currentpos = TellBlob(ofile); 00672 SeekBlob(ofile,savedpos,SEEK_SET); 00673 WriteBlobMSBLong(ofile,diff); 00674 SeekBlob(ofile,currentpos,SEEK_SET); 00675 savedolen = 0L; 00676 } 00677 if (outputlen & 1) 00678 { 00679 WriteBlobByte(ofile,0x00); 00680 outputlen++; 00681 } 00682 WriteBlobString(ofile,"8BIM"); 00683 WriteBlobMSBShort(ofile,recnum); 00684 outputlen += 6; 00685 if (name) 00686 nlen = strlen(name); 00687 WriteBlobByte(ofile,nlen); 00688 outputlen++; 00689 for (i=0; i<nlen; i++) 00690 WriteBlobByte(ofile,name[i]); 00691 outputlen += nlen; 00692 if ((nlen & 0x01) == 0) 00693 { 00694 WriteBlobByte(ofile,0x00); 00695 outputlen++; 00696 } 00697 if (recnum != IPTC_ID) 00698 { 00699 WriteBlobMSBLong(ofile, len); 00700 outputlen += 4; 00701 00702 next=0; 00703 outputlen += len; 00704 while (len--) 00705 WriteBlobByte(ofile,token[next++]); 00706 00707 if (outputlen & 1) 00708 { 00709 WriteBlobByte(ofile,0x00); 00710 outputlen++; 00711 } 00712 } 00713 else 00714 { 00715 /* patch in a fake length for now and fix it later */ 00716 savedpos = TellBlob(ofile); 00717 WriteBlobMSBLong(ofile,0xFFFFFFFFUL); 00718 outputlen += 4; 00719 savedolen = outputlen; 00720 } 00721 } 00722 else 00723 { 00724 if (len <= 0x7FFF) 00725 { 00726 WriteBlobByte(ofile,0x1c); 00727 WriteBlobByte(ofile,dataset); 00728 WriteBlobByte(ofile,recnum & 255); 00729 WriteBlobMSBShort(ofile,len); 00730 outputlen += 5; 00731 next=0; 00732 outputlen += len; 00733 while (len--) 00734 WriteBlobByte(ofile,token[next++]); 00735 } 00736 } 00737 } 00738 state++; 00739 } 00740 token=(char *) RelinquishMagickMemory(token); 00741 newstr=(char *) RelinquishMagickMemory(newstr); 00742 name=(char *) RelinquishMagickMemory(name); 00743 } 00744 line=(char *) RelinquishMagickMemory(line); 00745 if (savedolen > 0) 00746 { 00747 long diff = outputlen - savedolen; 00748 00749 currentpos = TellBlob(ofile); 00750 SeekBlob(ofile,savedpos,SEEK_SET); 00751 WriteBlobMSBLong(ofile,diff); 00752 SeekBlob(ofile,currentpos,SEEK_SET); 00753 savedolen = 0L; 00754 } 00755 return outputlen; 00756 } 00757 00758 /* some defines for the different JPEG block types */ 00759 #define M_SOF0 0xC0 /* Start Of Frame N */ 00760 #define M_SOF1 0xC1 /* N indicates which compression process */ 00761 #define M_SOF2 0xC2 /* Only SOF0-SOF2 are now in common use */ 00762 #define M_SOF3 0xC3 00763 #define M_SOF5 0xC5 /* NB: codes C4 and CC are NOT SOF markers */ 00764 #define M_SOF6 0xC6 00765 #define M_SOF7 0xC7 00766 #define M_SOF9 0xC9 00767 #define M_SOF10 0xCA 00768 #define M_SOF11 0xCB 00769 #define M_SOF13 0xCD 00770 #define M_SOF14 0xCE 00771 #define M_SOF15 0xCF 00772 #define M_SOI 0xD8 00773 #define M_EOI 0xD9 /* End Of Image (end of datastream) */ 00774 #define M_SOS 0xDA /* Start Of Scan (begins compressed data) */ 00775 #define M_APP0 0xe0 00776 #define M_APP1 0xe1 00777 #define M_APP2 0xe2 00778 #define M_APP3 0xe3 00779 #define M_APP4 0xe4 00780 #define M_APP5 0xe5 00781 #define M_APP6 0xe6 00782 #define M_APP7 0xe7 00783 #define M_APP8 0xe8 00784 #define M_APP9 0xe9 00785 #define M_APP10 0xea 00786 #define M_APP11 0xeb 00787 #define M_APP12 0xec 00788 #define M_APP13 0xed 00789 #define M_APP14 0xee 00790 #define M_APP15 0xef 00791 00792 static int jpeg_transfer_1(Image *ifile, Image *ofile) 00793 { 00794 int c; 00795 00796 c = ReadBlobByte(ifile); 00797 if (c == EOF) 00798 return EOF; 00799 WriteBlobByte(ofile,c); 00800 return c; 00801 } 00802 00803 #if defined(future) 00804 static int jpeg_skip_1(Image *ifile) 00805 { 00806 int c; 00807 00808 c = ReadBlobByte(ifile); 00809 if (c == EOF) 00810 return EOF; 00811 return c; 00812 } 00813 #endif 00814 00815 static int jpeg_read_remaining(Image *ifile, Image *ofile) 00816 { 00817 int c; 00818 00819 while ((c = jpeg_transfer_1(ifile, ofile)) != EOF) 00820 continue; 00821 return M_EOI; 00822 } 00823 00824 static int jpeg_skip_variable(Image *ifile, Image *ofile) 00825 { 00826 unsigned int length; 00827 int c1,c2; 00828 00829 if ((c1 = jpeg_transfer_1(ifile, ofile)) == EOF) 00830 return M_EOI; 00831 if ((c2 = jpeg_transfer_1(ifile, ofile)) == EOF) 00832 return M_EOI; 00833 00834 length = (((unsigned char) c1) << 8) + ((unsigned char) c2); 00835 length -= 2; 00836 00837 while (length--) 00838 if (jpeg_transfer_1(ifile, ofile) == EOF) 00839 return M_EOI; 00840 00841 return 0; 00842 } 00843 00844 static int jpeg_skip_variable2(Image *ifile, Image *ofile) 00845 { 00846 unsigned int length; 00847 int c1,c2; 00848 00849 if ((c1 = ReadBlobByte(ifile)) == EOF) return M_EOI; 00850 if ((c2 = ReadBlobByte(ifile)) == EOF) return M_EOI; 00851 00852 length = (((unsigned char) c1) << 8) + ((unsigned char) c2); 00853 length -= 2; 00854 00855 while (length--) 00856 if (ReadBlobByte(ifile) == EOF) 00857 return M_EOI; 00858 00859 return 0; 00860 } 00861 00862 static int jpeg_nextmarker(Image *ifile, Image *ofile) 00863 { 00864 int c; 00865 00866 /* transfer anything until we hit 0xff */ 00867 do 00868 { 00869 c = ReadBlobByte(ifile); 00870 if (c == EOF) 00871 return M_EOI; /* we hit EOF */ 00872 else 00873 if (c != 0xff) 00874 WriteBlobByte(ofile,c); 00875 } while (c != 0xff); 00876 00877 /* get marker byte, swallowing possible padding */ 00878 do 00879 { 00880 c = ReadBlobByte(ifile); 00881 if (c == EOF) 00882 return M_EOI; /* we hit EOF */ 00883 } while (c == 0xff); 00884 00885 return c; 00886 } 00887 00888 #if defined(future) 00889 static int jpeg_skip_till_marker(Image *ifile, int marker) 00890 { 00891 int c, i; 00892 00893 do 00894 { 00895 /* skip anything until we hit 0xff */ 00896 i = 0; 00897 do 00898 { 00899 c = ReadBlobByte(ifile); 00900 i++; 00901 if (c == EOF) 00902 return M_EOI; /* we hit EOF */ 00903 } while (c != 0xff); 00904 00905 /* get marker byte, swallowing possible padding */ 00906 do 00907 { 00908 c = ReadBlobByte(ifile); 00909 if (c == EOF) 00910 return M_EOI; /* we hit EOF */ 00911 } while (c == 0xff); 00912 } while (c != marker); 00913 return c; 00914 } 00915 #endif 00916 00917 static char psheader[] = "\xFF\xED\0\0Photoshop 3.0\08BIM\x04\x04\0\0\0\0"; 00918 00919 /* Embed binary IPTC data into a JPEG image. */ 00920 static int jpeg_embed(Image *ifile, Image *ofile, Image *iptc) 00921 { 00922 unsigned int marker; 00923 unsigned int done = 0; 00924 unsigned int len; 00925 int inx; 00926 00927 if (jpeg_transfer_1(ifile, ofile) != 0xFF) 00928 return 0; 00929 if (jpeg_transfer_1(ifile, ofile) != M_SOI) 00930 return 0; 00931 00932 while (done == MagickFalse) 00933 { 00934 marker = jpeg_nextmarker(ifile, ofile); 00935 if (marker == M_EOI) 00936 { /* EOF */ 00937 break; 00938 } 00939 else 00940 { 00941 if (marker != M_APP13) 00942 { 00943 WriteBlobByte(ofile,0xff); 00944 WriteBlobByte(ofile,marker); 00945 } 00946 } 00947 00948 switch (marker) 00949 { 00950 case M_APP13: 00951 /* we are going to write a new APP13 marker, so don't output the old one */ 00952 jpeg_skip_variable2(ifile, ofile); 00953 break; 00954 00955 case M_APP0: 00956 /* APP0 is in each and every JPEG, so when we hit APP0 we insert our new APP13! */ 00957 jpeg_skip_variable(ifile, ofile); 00958 00959 if (iptc != (Image *)NULL) 00960 { 00961 len=GetBlobSize(iptc); 00962 if (len & 1) 00963 len++; /* make the length even */ 00964 psheader[ 2 ] = (len+16)>>8; 00965 psheader[ 3 ] = (len+16)&0xff; 00966 for (inx = 0; inx < 18; inx++) 00967 WriteBlobByte(ofile,psheader[inx]); 00968 jpeg_read_remaining(iptc, ofile); 00969 len=GetBlobSize(iptc); 00970 if (len & 1) 00971 WriteBlobByte(ofile,0); 00972 } 00973 break; 00974 00975 case M_SOS: 00976 /* we hit data, no more marker-inserting can be done! */ 00977 jpeg_read_remaining(ifile, ofile); 00978 done = 1; 00979 break; 00980 00981 default: 00982 jpeg_skip_variable(ifile, ofile); 00983 break; 00984 } 00985 } 00986 return 1; 00987 } 00988 00989 /* handle stripping the APP13 data out of a JPEG */ 00990 #if defined(future) 00991 static void jpeg_strip(Image *ifile, Image *ofile) 00992 { 00993 unsigned int marker; 00994 00995 marker = jpeg_skip_till_marker(ifile, M_SOI); 00996 if (marker == M_SOI) 00997 { 00998 WriteBlobByte(ofile,0xff); 00999 WriteBlobByte(ofile,M_SOI); 01000 jpeg_read_remaining(ifile, ofile); 01001 } 01002 } 01003 01004 /* Extract any APP13 binary data into a file. */ 01005 static int jpeg_extract(Image *ifile, Image *ofile) 01006 { 01007 unsigned int marker; 01008 unsigned int done = 0; 01009 01010 if (jpeg_skip_1(ifile) != 0xff) 01011 return 0; 01012 if (jpeg_skip_1(ifile) != M_SOI) 01013 return 0; 01014 01015 while (done == MagickFalse) 01016 { 01017 marker = jpeg_skip_till_marker(ifile, M_APP13); 01018 if (marker == M_APP13) 01019 { 01020 marker = jpeg_nextmarker(ifile, ofile); 01021 break; 01022 } 01023 } 01024 return 1; 01025 } 01026 #endif 01027 01028 static Image *ReadMETAImage(const ImageInfo *image_info, 01029 ExceptionInfo *exception) 01030 { 01031 Image 01032 *buff, 01033 *image; 01034 01035 int 01036 c; 01037 01038 MagickBooleanType 01039 status; 01040 01041 size_t 01042 length; 01043 01044 StringInfo 01045 *profile; 01046 01047 void 01048 *blob; 01049 01050 /* 01051 Open file containing binary metadata 01052 */ 01053 assert(image_info != (const ImageInfo *) NULL); 01054 assert(image_info->signature == MagickSignature); 01055 if (image_info->debug != MagickFalse) 01056 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image_info->filename); 01057 assert(exception != (ExceptionInfo *) NULL); 01058 assert(exception->signature == MagickSignature); 01059 image=AllocateImage(image_info); 01060 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); 01061 if (status == MagickFalse) 01062 { 01063 DestroyImageList(image); 01064 return((Image *) NULL); 01065 } 01066 image->columns=1; 01067 image->rows=1; 01068 SetImage(image,OpaqueOpacity); 01069 length=1; 01070 if (LocaleNCompare(image_info->magick,"8BIM",4) == 0) 01071 { 01072 /* 01073 Read 8BIM binary metadata. 01074 */ 01075 buff=AllocateImage((ImageInfo *) NULL); 01076 if (buff == (Image *) NULL) 01077 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01078 blob=(unsigned char *) AcquireMagickMemory(length); 01079 if (blob == (unsigned char *) NULL) 01080 { 01081 buff=DestroyImage(buff); 01082 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01083 } 01084 AttachBlob(buff->blob,blob,length); 01085 if (LocaleCompare(image_info->magick,"8BIMTEXT") == 0) 01086 { 01087 length=parse8BIM(image, buff); 01088 if (length & 1) 01089 WriteBlobByte(buff,0x0); 01090 } 01091 else if (LocaleCompare(image_info->magick,"8BIMWTEXT") == 0) 01092 { 01093 length=parse8BIMW(image, buff); 01094 if (length & 1) 01095 WriteBlobByte(buff,0x0); 01096 } 01097 else 01098 { 01099 for ( ; ; ) 01100 { 01101 c=ReadBlobByte(image); 01102 if (c == EOF) 01103 break; 01104 WriteBlobByte(buff,c); 01105 } 01106 } 01107 profile=AcquireStringInfo(GetBlobSize(buff)); 01108 SetStringInfoDatum(profile,GetBlobStreamData(buff)); 01109 status=SetImageProfile(image,"iptc",profile); 01110 profile=DestroyStringInfo(profile); 01111 if (status == MagickFalse) 01112 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01113 blob=DetachBlob(buff->blob); 01114 blob=(unsigned char *) RelinquishMagickMemory(blob); 01115 buff=DestroyImage(buff); 01116 } 01117 if (LocaleNCompare(image_info->magick,"APP1",4) == 0) 01118 { 01119 char 01120 name[MaxTextExtent]; 01121 01122 (void) FormatMagickString(name,MaxTextExtent,"APP%d",1); 01123 buff=AllocateImage((ImageInfo *) NULL); 01124 if (buff == (Image *) NULL) 01125 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01126 blob=(unsigned char *) AcquireMagickMemory(length); 01127 if (blob == (unsigned char *) NULL) 01128 { 01129 buff=DestroyImage(buff); 01130 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01131 } 01132 AttachBlob(buff->blob,blob,length); 01133 if (LocaleCompare(image_info->magick,"APP1JPEG") == 0) 01134 { 01135 Image 01136 *iptc; 01137 01138 int 01139 result; 01140 01141 profile=(StringInfo *) image_info->client_data; 01142 if ((profile == (StringInfo *) NULL) || 01143 (profile->datum == (unsigned char *) NULL) || 01144 (profile->length == 0)) 01145 { 01146 blob=DetachBlob(buff->blob); 01147 blob=(char *) RelinquishMagickMemory(blob); 01148 buff=DestroyImage(buff); 01149 ThrowReaderException(CoderError,"NoIPTCProfileAvailable"); 01150 } 01151 iptc=AllocateImage((ImageInfo *) NULL); 01152 if (iptc == (Image *) NULL) 01153 { 01154 blob=DetachBlob(buff->blob); 01155 blob=(char *) RelinquishMagickMemory(blob); 01156 buff=DestroyImage(buff); 01157 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01158 } 01159 AttachBlob(iptc->blob,profile->datum,profile->length); 01160 result=jpeg_embed(image,buff,iptc); 01161 blob=DetachBlob(iptc->blob); 01162 blob=(char *) RelinquishMagickMemory(blob); 01163 iptc=DestroyImage(iptc); 01164 if (result == 0) 01165 { 01166 blob=DetachBlob(buff->blob); 01167 blob=(char *) RelinquishMagickMemory(blob); 01168 buff=DestroyImage(buff); 01169 ThrowReaderException(CoderError,"JPEGEmbeddingFailed"); 01170 } 01171 } 01172 else 01173 { 01174 #ifdef SLOW_METHOD 01175 for ( ; ; ) 01176 { 01177 /* Really - really slow - FIX ME PLEASE!!!! */ 01178 c=ReadBlobByte(image); 01179 if (c == EOF) 01180 break; 01181 WriteBlobByte(buff,c); 01182 } 01183 #else 01184 #define MaxBufferSize 65541 01185 long 01186 i; 01187 01188 unsigned char 01189 *buffer; 01190 01191 size_t 01192 length; 01193 01194 ssize_t 01195 count; 01196 01197 buffer=(unsigned char *) AcquireMagickMemory(MaxBufferSize); 01198 if (buffer != (unsigned char *) NULL) 01199 { 01200 i=0; 01201 while ((length=ReadBlob(image,MaxBufferSize,buffer)) != 0) 01202 { 01203 count=0; 01204 for (i=0; i < (long) length; i+=count) 01205 { 01206 count=WriteBlob(buff,length-i,buffer+i); 01207 if (count <= 0) 01208 break; 01209 } 01210 if (i < (long) length) 01211 break; 01212 } 01213 buffer=(unsigned char *) RelinquishMagickMemory(buffer); 01214 } 01215 #endif 01216 } 01217 profile=AcquireStringInfo(GetBlobSize(buff)); 01218 SetStringInfoDatum(profile,GetBlobStreamData(buff)); 01219 status=SetImageProfile(image,name,profile); 01220 profile=DestroyStringInfo(profile); 01221 if (status == MagickFalse) 01222 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01223 blob=DetachBlob(buff->blob); 01224 blob=(char *) RelinquishMagickMemory(blob); 01225 buff=DestroyImage(buff); 01226 } 01227 if ((LocaleCompare(image_info->magick,"ICC") == 0) || 01228 (LocaleCompare(image_info->magick,"ICM") == 0)) 01229 { 01230 buff=AllocateImage((ImageInfo *) NULL); 01231 if (buff == (Image *) NULL) 01232 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01233 blob=(unsigned char *) AcquireMagickMemory(length); 01234 if (blob == (unsigned char *) NULL) 01235 { 01236 buff=DestroyImage(buff); 01237 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01238 } 01239 AttachBlob(buff->blob,blob,length); 01240 for ( ; ; ) 01241 { 01242 c=ReadBlobByte(image); 01243 if (c == EOF) 01244 break; 01245 WriteBlobByte(buff,c); 01246 } 01247 profile=AcquireStringInfo(GetBlobSize(buff)); 01248 SetStringInfoDatum(profile,GetBlobStreamData(buff)); 01249 (void) SetImageProfile(image,"icc",profile); 01250 profile=DestroyStringInfo(profile); 01251 blob=DetachBlob(buff->blob); 01252 blob=(unsigned char *) RelinquishMagickMemory(blob); 01253 buff=DestroyImage(buff); 01254 } 01255 if (LocaleCompare(image_info->magick,"IPTC") == 0) 01256 { 01257 buff=AllocateImage((ImageInfo *) NULL); 01258 if (buff == (Image *) NULL) 01259 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01260 blob=(unsigned char *) AcquireMagickMemory(length); 01261 if (blob == (unsigned char *) NULL) 01262 { 01263 buff=DestroyImage(buff); 01264 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 01265 } 01266 AttachBlob(buff->blob,blob,length); 01267 /* write out the header - length field patched below */ 01268 WriteBlob(buff,12,(unsigned char *) "8BIM\04\04\0\0\0\0\0\0"); 01269 if (LocaleCompare(image_info->magick,"IPTCTEXT") == 0) 01270 { 01271 length=parse8BIM(image, buff); 01272 if (length & 1) 01273 WriteBlobByte(buff,0x0); 01274 } 01275 else if (LocaleCompare(image_info->magick,"IPTCWTEXT") == 0) 01276 { 01277 } 01278 else 01279 { 01280 for ( ; ; ) 01281 { 01282 c=ReadBlobByte(image); 01283 if (c == EOF) 01284 break; 01285 WriteBlobByte(buff,c); 01286 } 01287 } 01288 profile=AcquireStringInfo(GetBlobSize(buff)); 01289 /* 01290 subtract off the length of the 8BIM stuff. 01291 */ 01292 length=profile->length-12; 01293 profile->datum[10]=length >> 8; 01294 profile->datum[11]=length & 0xff; 01295 SetStringInfoDatum(profile,GetBlobStreamData(buff)); 01296 (void) SetImageProfile(image,"iptc",profile); 01297 profile=DestroyStringInfo(profile); 01298 blob=DetachBlob(buff->blob); 01299 blob=(unsigned char *) RelinquishMagickMemory(blob); 01300 buff=DestroyImage(buff); 01301 } 01302 CloseBlob(image); 01303 return(GetFirstImageInList(image)); 01304 } 01305 01306 /* 01307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01308 % % 01309 % % 01310 % % 01311 % R e g i s t e r M E T A I m a g e % 01312 % % 01313 % % 01314 % % 01315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01316 % 01317 % RegisterMETAImage() adds attributes for the META image format to 01318 % the list of supported formats. The attributes include the image format 01319 % tag, a method to read and/or write the format, whether the format 01320 % supports the saving of more than one frame to the same file or blob, 01321 % whether the format supports native in-memory I/O, and a brief 01322 % description of the format. 01323 % 01324 % The format of the RegisterMETAImage method is: 01325 % 01326 % RegisterMETAImage(void) 01327 % 01328 */ 01329 ModuleExport void RegisterMETAImage(void) 01330 { 01331 MagickInfo 01332 *entry; 01333 01334 entry=SetMagickInfo("8BIM"); 01335 entry->decoder=(DecoderHandler *) ReadMETAImage; 01336 entry->encoder=(EncoderHandler *) WriteMETAImage; 01337 entry->adjoin=MagickFalse; 01338 entry->stealth=MagickTrue; 01339 entry->seekable_stream=MagickTrue; 01340 entry->description=AcquireString("Photoshop resource format"); 01341 entry->module=AcquireString("META"); 01342 (void) RegisterMagickInfo(entry); 01343 01344 entry=SetMagickInfo("8BIMTEXT"); 01345 entry->decoder=(DecoderHandler *) ReadMETAImage; 01346 entry->encoder=(EncoderHandler *) WriteMETAImage; 01347 entry->adjoin=MagickFalse; 01348 entry->stealth=MagickTrue; 01349 entry->seekable_stream=MagickTrue; 01350 entry->description=AcquireString("Photoshop resource text format"); 01351 entry->module=AcquireString("META"); 01352 (void) RegisterMagickInfo(entry); 01353 01354 entry=SetMagickInfo("8BIMWTEXT"); 01355 entry->decoder=(DecoderHandler *) ReadMETAImage; 01356 entry->encoder=(EncoderHandler *) WriteMETAImage; 01357 entry->adjoin=MagickFalse; 01358 entry->stealth=MagickTrue; 01359 entry->seekable_stream=MagickTrue; 01360 entry->description=AcquireString("Photoshop resource wide text format"); 01361 entry->module=AcquireString("META"); 01362 (void) RegisterMagickInfo(entry); 01363 01364 entry=SetMagickInfo("APP1"); 01365 entry->decoder=(DecoderHandler *) ReadMETAImage; 01366 entry->encoder=(EncoderHandler *) WriteMETAImage; 01367 entry->adjoin=MagickFalse; 01368 entry->stealth=MagickTrue; 01369 entry->seekable_stream=MagickTrue; 01370 entry->description=AcquireString("Raw application information"); 01371 entry->module=AcquireString("META"); 01372 (void) RegisterMagickInfo(entry); 01373 01374 entry=SetMagickInfo("APP1JPEG"); 01375 entry->decoder=(DecoderHandler *) ReadMETAImage; 01376 entry->encoder=(EncoderHandler *) WriteMETAImage; 01377 entry->adjoin=MagickFalse; 01378 entry->stealth=MagickTrue; 01379 entry->seekable_stream=MagickTrue; 01380 entry->description=AcquireString("Raw JPEG binary data"); 01381 entry->module=AcquireString("META"); 01382 (void) RegisterMagickInfo(entry); 01383 01384 entry=SetMagickInfo("EXIF"); 01385 entry->decoder=(DecoderHandler *) ReadMETAImage; 01386 entry->encoder=(EncoderHandler *) WriteMETAImage; 01387 entry->adjoin=MagickFalse; 01388 entry->stealth=MagickTrue; 01389 entry->seekable_stream=MagickTrue; 01390 entry->description=AcquireString("Exif digital camera binary data"); 01391 entry->module=AcquireString("META"); 01392 (void) RegisterMagickInfo(entry); 01393 01394 entry=SetMagickInfo("XMP"); 01395 entry->decoder=(DecoderHandler *) ReadMETAImage; 01396 entry->encoder=(EncoderHandler *) WriteMETAImage; 01397 entry->adjoin=MagickFalse; 01398 entry->stealth=MagickTrue; 01399 entry->seekable_stream=MagickTrue; 01400 entry->description=AcquireString("Adobe XML metadata"); 01401 entry->module=AcquireString("META"); 01402 (void) RegisterMagickInfo(entry); 01403 01404 entry=SetMagickInfo("ICM"); 01405 entry->decoder=(DecoderHandler *) ReadMETAImage; 01406 entry->encoder=(EncoderHandler *) WriteMETAImage; 01407 entry->adjoin=MagickFalse; 01408 entry->stealth=MagickTrue; 01409 entry->seekable_stream=MagickTrue; 01410 entry->description=AcquireString("ICC Color Profile"); 01411 entry->module=AcquireString("META"); 01412 (void) RegisterMagickInfo(entry); 01413 01414 entry=SetMagickInfo("ICC"); 01415 entry->decoder=(DecoderHandler *) ReadMETAImage; 01416 entry->encoder=(EncoderHandler *) WriteMETAImage; 01417 entry->adjoin=MagickFalse; 01418 entry->stealth=MagickTrue; 01419 entry->seekable_stream=MagickTrue; 01420 entry->description=AcquireString("ICC Color Profile"); 01421 entry->module=AcquireString("META"); 01422 (void) RegisterMagickInfo(entry); 01423 01424 entry=SetMagickInfo("IPTC"); 01425 entry->decoder=(DecoderHandler *) ReadMETAImage; 01426 entry->encoder=(EncoderHandler *) WriteMETAImage; 01427 entry->adjoin=MagickFalse; 01428 entry->stealth=MagickTrue; 01429 entry->seekable_stream=MagickTrue; 01430 entry->description=AcquireString("IPTC Newsphoto"); 01431 entry->module=AcquireString("META"); 01432 (void) RegisterMagickInfo(entry); 01433 01434 entry=SetMagickInfo("IPTCTEXT"); 01435 entry->decoder=(DecoderHandler *) ReadMETAImage; 01436 entry->encoder=(EncoderHandler *) WriteMETAImage; 01437 entry->adjoin=MagickFalse; 01438 entry->stealth=MagickTrue; 01439 entry->seekable_stream=MagickTrue; 01440 entry->description=AcquireString("IPTC Newsphoto text format"); 01441 entry->module=AcquireString("META"); 01442 (void) RegisterMagickInfo(entry); 01443 01444 entry=SetMagickInfo("IPTCWTEXT"); 01445 entry->decoder=(DecoderHandler *) ReadMETAImage; 01446 entry->encoder=(EncoderHandler *) WriteMETAImage; 01447 entry->adjoin=MagickFalse; 01448 entry->stealth=MagickTrue; 01449 entry->seekable_stream=MagickTrue; 01450 entry->description=AcquireString("IPTC Newsphoto text format"); 01451 entry->module=AcquireString("META"); 01452 (void) RegisterMagickInfo(entry); 01453 } 01454 01455 /* 01456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01457 % % 01458 % % 01459 % % 01460 % U n r e g i s t e r M E T A I m a g e % 01461 % % 01462 % % 01463 % % 01464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01465 % 01466 % UnregisterMETAImage() removes format registrations made by the 01467 % META module from the list of supported formats. 01468 % 01469 % The format of the UnregisterMETAImage method is: 01470 % 01471 % UnregisterMETAImage(void) 01472 % 01473 */ 01474 ModuleExport void UnregisterMETAImage(void) 01475 { 01476 (void) UnregisterMagickInfo("8BIM"); 01477 (void) UnregisterMagickInfo("8BIMTEXT"); 01478 (void) UnregisterMagickInfo("8BIMWTEXT"); 01479 (void) UnregisterMagickInfo("EXIF"); 01480 (void) UnregisterMagickInfo("APP1"); 01481 (void) UnregisterMagickInfo("APP1JPEG"); 01482 (void) UnregisterMagickInfo("ICCTEXT"); 01483 (void) UnregisterMagickInfo("ICM"); 01484 (void) UnregisterMagickInfo("ICC"); 01485 (void) UnregisterMagickInfo("IPTC"); 01486 (void) UnregisterMagickInfo("IPTCTEXT"); 01487 (void) UnregisterMagickInfo("IPTCWTEXT"); 01488 (void) UnregisterMagickInfo("XMP"); 01489 } 01490 01491 /* 01492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01493 % % 01494 % % 01495 % % 01496 % W r i t e M E T A I m a g e % 01497 % % 01498 % % 01499 % % 01500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01501 % 01502 % WriteMETAImage() writes a META image to a file. 01503 % 01504 % The format of the WriteMETAImage method is: 01505 % 01506 % MagickBooleanType WriteMETAImage(const ImageInfo *image_info, 01507 % Image *image) 01508 % 01509 % Compression code contributed by Kyle Shorter. 01510 % 01511 % A description of each parameter follows: 01512 % 01513 % o image_info: Specifies a pointer to an ImageInfo structure. 01514 % 01515 % o image: A pointer to a Image structure. 01516 % 01517 % 01518 */ 01519 01520 static long GetIPTCStream(unsigned char