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

Go to the documentation of this file.
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % M M PPPP EEEEE GGGG % 00007 % MM MM P P E G % 00008 % M M M PPPP EEE G GG % 00009 % M M P E G G % 00010 % M M P EEEEE GGGG % 00011 % % 00012 % % 00013 % Write MPEG Image Format. % 00014 % % 00015 % Software Design % 00016 % John Cristy % 00017 % July 1999 % 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 Include declarations. 00040 */ 00041 #include "magick/studio.h" 00042 #include "magick/blob.h" 00043 #include "magick/blob_private.h" 00044 #include "magick/constitute.h" 00045 #include "magick/delegate.h" 00046 #include "magick/error.h" 00047 #include "magick/error_private.h" 00048 #include "magick/geometry.h" 00049 #include "magick/image.h" 00050 #include "magick/image_private.h" 00051 #include "magick/list.h" 00052 #include "magick/log.h" 00053 #include "magick/magick.h" 00054 #include "magick/memory_.h" 00055 #include "magick/resource_.h" 00056 #include "magick/static.h" 00057 #include "magick/string_.h" 00058 #include "magick/transform.h" 00059 #include "magick/utility.h" 00060 00061 /* 00062 Forward declarations. 00063 */ 00064 static MagickBooleanType 00065 WriteMPEGImage(const ImageInfo *image_info,Image *image); 00066 00067 /* 00068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00069 % % 00070 % % 00071 % % 00072 % I s M P E G % 00073 % % 00074 % % 00075 % % 00076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00077 % 00078 % IsMPEG() returns MagickTrue if the image format type, identified by the 00079 % magick string, is MPEG. 00080 % 00081 % The format of the IsMPEG method is: 00082 % 00083 % MagickBooleanType IsMPEG(const unsigned char *magick,const size_t length) 00084 % 00085 % A description of each parameter follows: 00086 % 00087 % o magick: This string is generally the first few bytes of an image file 00088 % or blob. 00089 % 00090 % o length: Specifies the length of the magick string. 00091 % 00092 % 00093 */ 00094 static MagickBooleanType IsMPEG(const unsigned char *magick,const size_t length) 00095 { 00096 if (length < 4) 00097 return(MagickFalse); 00098 if (memcmp(magick,"\000\000\001\263",4) == 0) 00099 return(MagickTrue); 00100 return(MagickFalse); 00101 } 00102 00103 /* 00104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00105 % % 00106 % % 00107 % % 00108 % R e a d M P E G I m a g e % 00109 % % 00110 % % 00111 % % 00112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00113 % 00114 % ReadMPEGImage() reads an binary file in the MPEG video stream format 00115 % and returns it. It allocates the memory necessary for the new Image 00116 % structure and returns a pointer to the new image. This method differs from 00117 % the other decoder methods in that only the Photoshop resource (MPEG) 00118 % information is useful in the returned image. 00119 % 00120 % The format of the ReadMPEGImage method is: 00121 % 00122 % Image *ReadMPEGImage(const ImageInfo *image_info, 00123 % ExceptionInfo *exception) 00124 % 00125 % A description of each parameter follows: 00126 % 00127 % o image_info: The image info. 00128 % 00129 % o exception: return any errors or warnings in this structure. 00130 % 00131 % 00132 */ 00133 static Image *ReadMPEGImage(const ImageInfo *image_info, 00134 ExceptionInfo *exception) 00135 { 00136 Image 00137 *image, 00138 *images; 00139 00140 ImageInfo 00141 *read_info; 00142 00143 MagickBooleanType 00144 status; 00145 00146 register long 00147 i; 00148 00149 /* 00150 Open image file. 00151 */ 00152 assert(image_info != (const ImageInfo *) NULL); 00153 assert(image_info->signature == MagickSignature); 00154 if (image_info->debug != MagickFalse) 00155 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image_info->filename); 00156 assert(exception != (ExceptionInfo *) NULL); 00157 assert(exception->signature == MagickSignature); 00158 image=AllocateImage(image_info); 00159 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); 00160 if (status == MagickFalse) 00161 { 00162 DestroyImageList(image); 00163 return((Image *) NULL); 00164 } 00165 CloseBlob(image); 00166 /* 00167 Convert MPEG to PPM with delegate. 00168 */ 00169 image=AllocateImage(image_info); 00170 read_info=CloneImageInfo(image_info); 00171 (void) InvokeDelegate(read_info,image,"mpeg-decode",(char *) NULL,exception); 00172 image=DestroyImage(image); 00173 /* 00174 Read PPM files. 00175 */ 00176 images=NewImageList(); 00177 for (i=(long) read_info->scene; ; i++) 00178 { 00179 (void) FormatMagickString(read_info->filename,MaxTextExtent, 00180 "%s%ld.ppm",read_info->unique,i); 00181 if (IsAccessible(read_info->filename) == MagickFalse) 00182 break; 00183 image=ReadImage(read_info,exception); 00184 if (image == (Image *) NULL) 00185 break; 00186 (void) strcpy(image->magick,image_info->magick); 00187 image->scene=(unsigned long) i; 00188 AppendImageToList(&images,image); 00189 if (read_info->number_scenes != 0) 00190 if (i >= (long) (read_info->scene+read_info->number_scenes-1)) 00191 break; 00192 } 00193 /* 00194 Free resources. 00195 */ 00196 for (i=0; ; i++) 00197 { 00198 (void) FormatMagickString(read_info->filename,MaxTextExtent, 00199 "%s%ld.ppm",read_info->unique,i); 00200 if (IsAccessible(read_info->filename) == MagickFalse) 00201 break; 00202 (void) remove(read_info->filename); 00203 } 00204 read_info=DestroyImageInfo(read_info); 00205 return(images); 00206 } 00207 00208 /* 00209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00210 % % 00211 % % 00212 % % 00213 % R e g i s t e r M P E G I m a g e % 00214 % % 00215 % % 00216 % % 00217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00218 % 00219 % RegisterMPEGImage() adds attributes for the MPEG image format to 00220 % the list of supported formats. The attributes include the image format 00221 % tag, a method to read and/or write the format, whether the format 00222 % supports the saving of more than one frame to the same file or blob, 00223 % whether the format supports native in-memory I/O, and a brief 00224 % description of the format. 00225 % 00226 % The format of the RegisterMPEGImage method is: 00227 % 00228 % RegisterMPEGImage(void) 00229 % 00230 */ 00231 ModuleExport void RegisterMPEGImage(void) 00232 { 00233 MagickInfo 00234 *entry; 00235 00236 entry=SetMagickInfo("MPEG"); 00237 entry->decoder=(DecoderHandler *) ReadMPEGImage; 00238 entry->encoder=(EncoderHandler *) WriteMPEGImage; 00239 entry->magick=(MagickHandler *) IsMPEG; 00240 entry->blob_support=MagickFalse; 00241 entry->description=AcquireString("MPEG Video Stream"); 00242 entry->module=AcquireString("MPEG"); 00243 (void) RegisterMagickInfo(entry); 00244 entry=SetMagickInfo("MPG"); 00245 entry->decoder=(DecoderHandler *) ReadMPEGImage; 00246 entry->encoder=(EncoderHandler *) WriteMPEGImage; 00247 entry->magick=(MagickHandler *) IsMPEG; 00248 entry->blob_support=MagickFalse; 00249 entry->description=AcquireString("MPEG Video Stream"); 00250 entry->module=AcquireString("MPEG"); 00251 (void) RegisterMagickInfo(entry); 00252 entry=SetMagickInfo("M2V"); 00253 entry->decoder=(DecoderHandler *) ReadMPEGImage; 00254 entry->encoder=(EncoderHandler *) WriteMPEGImage; 00255 entry->magick=(MagickHandler *) IsMPEG; 00256 entry->blob_support=MagickFalse; 00257 entry->description=AcquireString("MPEG Video Stream"); 00258 entry->module=AcquireString("MPEG"); 00259 (void) RegisterMagickInfo(entry); 00260 } 00261 00262 /* 00263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00264 % % 00265 % % 00266 % % 00267 % U n r e g i s t e r M P E G I m a g e % 00268 % % 00269 % % 00270 % % 00271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00272 % 00273 % UnregisterMPEGImage() removes format registrations made by the 00274 % BIM module from the list of supported formats. 00275 % 00276 % The format of the UnregisterBIMImage method is: 00277 % 00278 % UnregisterMPEGImage(void) 00279 % 00280 */ 00281 ModuleExport void UnregisterMPEGImage(void) 00282 { 00283 (void) UnregisterMagickInfo("M2V"); 00284 (void) UnregisterMagickInfo("MPEG"); 00285 (void) UnregisterMagickInfo("MPG"); 00286 } 00287 00288 /* 00289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00290 % % 00291 % % 00292 % % 00293 % W r i t e M P E G I m a g e % 00294 % % 00295 % % 00296 % % 00297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00298 % 00299 % WriteMPEGImage() writes an image to a file in MPEG video stream format. 00300 % Lawrence Livermore National Laboratory (LLNL) contributed code to adjust 00301 % the MPEG parameters to correspond to the compression quality setting. 00302 % 00303 % The format of the WriteMPEGImage method is: 00304 % 00305 % MagickBooleanType WriteMPEGImage(const ImageInfo *image_info,Image *image) 00306 % 00307 % A description of each parameter follows. 00308 % 00309 % o image_info: The image info. 00310 % 00311 % o image: The image. 00312 % 00313 % 00314 */ 00315 00316 static MagickBooleanType WriteMPEGParameterFiles(const ImageInfo *image_info, 00317 Image *image,const char *basename) 00318 { 00319 char 00320 filename[MaxTextExtent]; 00321 00322 double 00323 q; 00324 00325 FILE 00326 *file, 00327 *parameter_file; 00328 00329 long 00330 quant, 00331 vertical_factor; 00332 00333 MagickBooleanType 00334 mpeg; 00335 00336 register Image 00337 *p; 00338 00339 register long 00340 i; 00341 00342 ssize_t 00343 count; 00344 00345 static int 00346 q_matrix[]= 00347 { 00348 8, 16, 19, 22, 26, 27, 29, 34, 00349 16, 16, 22, 24, 27, 29, 34, 37, 00350 19, 22, 26, 27, 29, 34, 34, 38, 00351 22, 22, 26, 27, 29, 34, 37, 40, 00352 22, 26, 27, 29, 32, 35, 40, 48, 00353 26, 27, 29, 32, 35, 40, 48, 58, 00354 26, 27, 29, 34, 38, 46, 56, 69, 00355 27, 29, 35, 38, 46, 56, 69, 83 00356 }; 00357 00358 /* 00359 Write parameter file (see mpeg2encode documentation for details). 00360 */ 00361 file=fopen(basename,"w"); 00362 if (file == (FILE *) NULL) 00363 return(MagickFalse); 00364 (void) fprintf(file,"MPEG\n"); /* comment */ 00365 (void) fprintf(file,"%s.%%d\n",image->filename); /* source frame file */ 00366 (void) fprintf(file,"-\n"); /* reconstructed frame file */ 00367 if (image->quality == UndefinedCompressionQuality) 00368 (void) fprintf(file,"-\n"); /* default intra quant matrix */ 00369 else 00370 { 00371 /* 00372 Write intra quant matrix file. 00373 */ 00374 (void) FormatMagickString(filename,MaxTextExtent,"%s.iqm",basename); 00375 (void) fprintf(file,"%s\n",filename); 00376 parameter_file=fopen(filename,"w"); 00377 if (parameter_file == (FILE *) NULL) 00378 return(MagickFalse); 00379 if (image->quality >= 75) 00380 { 00381 q=(double) Max((image->quality-75)*2,1); 00382 for (i=0; i < 64; i++) 00383 { 00384 quant=(long) Min(Max(q_matrix[i]/q,1.0),255.0); 00385 (void) fprintf(parameter_file," %ld",quant); 00386 if ((i % 8) == 7) 00387 (void) fprintf(parameter_file,"\n"); 00388 } 00389 } 00390 else 00391 { 00392 q=(double) Max((75-image->quality)/8,1); 00393 for (i=0; i < 64; i++) 00394 { 00395 quant=(long) Min(Max(q*q_matrix[i]+0.5,1.0),255.0); 00396 (void) fprintf(parameter_file," %ld",quant); 00397 if ((i % 8) == 7) 00398 (void) fprintf(parameter_file,"\n"); 00399 } 00400 } 00401 (void) fclose(parameter_file); 00402 } 00403 if (image->quality == UndefinedCompressionQuality) 00404 (void) fprintf(file,"-\n"); /* default non intra quant matrix */ 00405 else 00406 { 00407 /* 00408 Write non intra quant matrix file. 00409 */ 00410 (void) FormatMagickString(filename,MaxTextExtent,"%s.niq",basename); 00411 (void) fprintf(file,"%s\n",filename); 00412 parameter_file=fopen(filename,"w"); 00413 if (parameter_file == (FILE *) NULL) 00414 return(MagickFalse); 00415 q=Min(Max(66.0-(2*image->quality)/3.0,1.0),255); 00416 for (i=0; i < 64; i++) 00417 { 00418 (void) fprintf(parameter_file," %d",(int) q); 00419 if ((i % 8) == 7) 00420 (void) fprintf(parameter_file,"\n"); 00421 } 00422 (void) fclose(parameter_file); 00423 } 00424 (void) fprintf(file,"%s.log\n",basename); /* statistics log */ 00425 (void) fprintf(file,"1\n"); /* input picture file format */ 00426 count=0; 00427 for (p=image; p != (Image *) NULL; p=p->next) 00428 count+=Max((p->delay+1)/3,1); 00429 (void) fprintf(file,"%lu\n",(unsigned long) count); /* number of frames */ 00430 (void) fprintf(file,"0\n"); /* number of first frame */ 00431 (void) fprintf(file,"00:00:00:00\n"); /* timecode of first frame */ 00432 mpeg=(MagickBooleanType) (LocaleCompare(image_info->magick,"M2V") != 0); 00433 if (image->quality > 98) 00434 (void) fprintf(file,"1\n"); 00435 else 00436 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 12 : 15); 00437 if (image->quality > 98) 00438 (void) fprintf(file,"1\n"); 00439 else 00440 (void) fprintf(file,"3\n"); 00441 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 1 : 0); /* ISO/IEC 11172-2 stream */ 00442 (void) fprintf(file,"0\n"); /* select frame picture coding */ 00443 (void) fprintf(file,"%lu\n",image->columns+ 00444 ((image->columns & 0x01) != 0 ? 1 : 0)); 00445 (void) fprintf(file,"%lu\n",image->rows+((image->rows & 0x01) != 0 ? 1 : 0)); 00446 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 8 : 2); /* aspect ratio */ 00447 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 3 : 5); /* frame rate code */ 00448 (void) fprintf(file,"%g\n",mpeg != MagickFalse ? 1152000.0 : 5000000.0); /* bit rate */ 00449 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 20 : 112); /* vbv buffer size */ 00450 (void) fprintf(file,"0\n"); /* low delay */ 00451 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 1 : 0); /* constrained parameter */ 00452 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 4 : 1); /* profile ID */ 00453 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 8 : 4); /* level ID */ 00454 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 1 : 0); /* progressive sequence */ 00455 vertical_factor=2; 00456 if (image_info->sampling_factor != (char *) NULL) 00457 { 00458 GeometryInfo 00459 geometry_info; 00460 00461 long 00462 horizontal_factor; 00463 00464 MagickStatusType 00465 flags; 00466 00467 flags=ParseGeometry(image_info->sampling_factor,&geometry_info); 00468 horizontal_factor=(long) geometry_info.rho; 00469 vertical_factor=(long) geometry_info.sigma; 00470 if ((flags & SigmaValue) == 0) 00471 vertical_factor=horizontal_factor; 00472 if (mpeg != MagickFalse) 00473 { 00474 if ((horizontal_factor != 2) || (vertical_factor != 2)) 00475 { 00476 (void) fclose(file); 00477 return(MagickFalse); 00478 } 00479 } 00480 else 00481 if ((horizontal_factor != 2) || 00482 ((vertical_factor != 1) && (vertical_factor != 2))) 00483 { 00484 (void) fclose(file); 00485 return(MagickFalse); 00486 } 00487 } 00488 (void) fprintf(file,"%d\n",vertical_factor == 2 ? 1 : 2); /* chroma format */ 00489 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 1 : 2); /* video format */ 00490 (void) fprintf(file,"5\n"); /* color primaries */ 00491 (void) fprintf(file,"5\n"); /* transfer characteristics */ 00492 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 5 : 4); /* matrix coefficients */ 00493 (void) fprintf(file,"%lu\n",image->columns+ 00494 ((image->columns & 0x01) != 0 ? 1 : 0)); 00495 (void) fprintf(file,"%lu\n",image->rows+((image->rows & 0x01) != 0 ? 1 : 0)); 00496 (void) fprintf(file,"0\n"); /* intra dc precision */ 00497 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 0 : 1); /* top field */ 00498 (void) fprintf(file,"%d %d %d\n",mpeg != MagickFalse ? 1 : 0, 00499 mpeg != MagickFalse ? 1 : 0, mpeg != MagickFalse ? 1 : 0); 00500 (void) fprintf(file,"0 0 0\n"); /* concealment motion vector */ 00501 (void) fprintf(file,"%d %d %d\n",mpeg != MagickFalse ? 0 : 1, 00502 mpeg != MagickFalse ? 0 : 1,mpeg != MagickFalse ? 0 : 1); 00503 (void) fprintf(file,"%d 0 0\n",mpeg != MagickFalse ? 0 : 1); /* intra vlc format */ 00504 (void) fprintf(file,"0 0 0\n"); /* alternate scan */ 00505 (void) fprintf(file,"0\n"); /* repeat first field */ 00506 (void) fprintf(file,"%d\n",mpeg != MagickFalse ? 1 : 0); /* progressive frame */ 00507 (void) fprintf(file,"0\n"); /* intra slice refresh period */ 00508 (void) fprintf(file,"0\n"); /* reaction parameter */ 00509 (void) fprintf(file,"0\n"); /* initial average activity */ 00510 (void) fprintf(file,"0\n"); 00511 (void) fprintf(file,"0\n"); 00512 (void) fprintf(file,"0\n"); 00513 (void) fprintf(file,"0\n"); 00514 (void) fprintf(file,"0\n"); 00515 (void) fprintf(file,"0\n"); 00516 (void) fprintf(file,"2 2 11 11\n"); 00517 (void) fprintf(file,"1 1 3 3\n"); 00518 (void) fprintf(file,"1 1 7 7\n"); 00519 (void) fprintf(file,"1 1 7 7\n"); 00520 (void) fprintf(file,"1 1 3 3\n"); 00521 (void) fclose(file); 00522 return(MagickTrue); 00523 } 00524 00525 static MagickBooleanType WriteMPEGImage(const ImageInfo *image_info,Image *image) 00526 { 00527 char 00528 basename[MaxTextExtent], 00529 filename[MaxTextExtent]; 00530 00531 Image 00532 *coalesce_image, 00533 *next_image; 00534 00535 ImageInfo 00536 *write_info; 00537 00538 int 00539 file; 00540 00541 MagickBooleanType 00542 status; 00543 00544 register Image 00545 *p; 00546 00547 register long 00548 i; 00549 00550 size_t 00551 length; 00552 00553 unsigned char 00554 *blob; 00555 00556 unsigned long 00557 count, 00558 scene; 00559 00560 /* 00561 Open output image file. 00562 */ 00563 assert(image_info != (const ImageInfo *) NULL); 00564 assert(image_info->signature == MagickSignature); 00565 assert(image != (Image *) NULL); 00566 assert(image->signature == MagickSignature); 00567 if (image->debug != MagickFalse) 00568 (void) LogMagickEvent(TraceEvent,GetMagickModule(),image->filename); 00569 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); 00570 if (status == MagickFalse) 00571 return(status); 00572 CloseBlob(image); 00573 /* 00574 Determine if the sequence of images have identical page info. 00575 */ 00576 coalesce_image=image; 00577 for (next_image=image; next_image != (Image *) NULL; ) 00578 { 00579 if ((image->columns != next_image->columns) || 00580 (image->rows != next_image->rows)) 00581 break; 00582 if ((image->page.x != next_image->page.x) || 00583 (image->page.y != next_image->page.y)) 00584 break; 00585 next_image=next_image->next; 00586 } 00587 if (next_image != (Image *) NULL) 00588 { 00589 coalesce_image=CoalesceImages(image,&image->exception); 00590 if (coalesce_image == (Image *) NULL) 00591 return(MagickFalse); 00592 } 00593 /* 00594 Write YUV files. 00595 */ 00596 file=AcquireUniqueFileResource(basename); 00597 if (file != -1) 00598 (void) close(file); 00599 (void) FormatMagickString(coalesce_image->filename,MaxTextExtent,"%s", 00600 basename); 00601 write_info=CloneImageInfo(image_info); 00602 status=WriteMPEGParameterFiles(write_info,coalesce_image,basename); 00603 if (status == MagickFalse) 00604 { 00605 if (coalesce_image != image) 00606 coalesce_image=DestroyImage(coalesce_image); 00607 (void) remove(basename); 00608 if (image->quality != UndefinedCompressionQuality) 00609 { 00610 (void) FormatMagickString(filename,MaxTextExtent,"%s.iqm", 00611 basename); 00612 (void) remove(filename); 00613 (void) FormatMagickString(filename,MaxTextExtent,"%s.niq", 00614 basename); 00615 (void) remove(filename); 00616 } 00617 ThrowWriterException(CoderError,"UnableToWriteMPEGParameters"); 00618 } 00619 count=0; 00620 write_info->interlace=PlaneInterlace; 00621 for (p=coalesce_image; p != (Image *) NULL; p=p->next) 00622 { 00623 char 00624 previous_image[MaxTextExtent]; 00625 00626 blob=(unsigned char *) NULL; 00627 length=0; 00628 scene=p->scene; 00629 for (i=0; i < (long) Max((p->delay+1)/3,1); i++) 00630 { 00631 p->scene=count; 00632 count++; 00633 status=MagickFalse; 00634 switch (i) 00635 { 00636 case 0: 00637 { 00638 Image 00639 *frame; 00640 00641 (void) FormatMagickString(p->filename,MaxTextExtent,"%s.%lu.yuv", 00642 basename,p->scene); 00643 (void) FormatMagickString(filename,MaxTextExtent,"%s.%lu.yuv", 00644 basename,p->scene); 00645 (void) FormatMagickString(previous_image,MaxTextExtent, 00646 "%s.%lu.yuv",basename,p->scene); 00647 frame=CloneImage(p,0,0,MagickTrue,&p->exception); 00648 if (frame == (Image *) NULL) 00649 break; 00650 status=WriteImage(write_info,frame); 00651 frame=DestroyImage(frame); 00652 break; 00653 } 00654 case 1: 00655 { 00656 blob=(unsigned char *) 00657 FileToBlob(previous_image,&length,&image->exception); 00658 } 00659 default: 00660 { 00661 (void) FormatMagickString(filename,MaxTextExtent,"%s.%lu.yuv", 00662 basename,p->scene); 00663 if (length > 0) 00664 status=BlobToFile(filename,blob,length,&image->exception); 00665 break; 00666 } 00667 } 00668 if (image->debug != MagickFalse) 00669 { 00670 if (status != MagickFalse) 00671 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 00672 "%lu. Wrote YUV file for scene %lu:",i,p->scene); 00673 else 00674 (void) LogMagickEvent(CoderEvent,GetMagickModule(), 00675 "%lu. Failed to write YUV file for scene %lu:",i,p->scene); 00676 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%s", 00677 filename); 00678 } 00679 } 00680 p->scene=scene; 00681 if (blob != (unsigned char *) NULL) 00682 blob=(unsigned char *) RelinquishMagickMemory(blob); 00683 if (status == MagickFalse) 00684 break; 00685 } 00686 /* 00687 Convert YUV to MPEG. 00688 */ 00689 (void) CopyMagickString(coalesce_image->filename,basename,MaxTextExtent); 00690 status=InvokeDelegate(write_info,coalesce_image,(char *) NULL,"mpeg-encode", 00691 &image->exception); 00692 write_info=DestroyImageInfo(write_info); 00693 /* 00694 Free resources. 00695 */ 00696 count=0; 00697 for (p=coalesce_image; p != (Image *) NULL; p=p->next) 00698 { 00699 for (i=0; i < (long) Max((p->delay+1)/3,1); i++) 00700 { 00701 (void) FormatMagickString(p->filename,MaxTextExtent,"%s.%lu.yuv", 00702 basename,count++); 00703 (void) remove(p->filename); 00704 } 00705 (void) CopyMagickString(p->filename,image_info->filename,MaxTextExtent); 00706 } 00707 (void) RelinquishUniqueFileResource(basename); 00708 (void) FormatMagickString(filename,MaxTextExtent,"%s.iqm",basename); 00709 (void) remove(filename); 00710 (void) FormatMagickString(filename,MaxTextExtent,"%s.niq",basename); 00711 (void) remove(filename); 00712 (void) FormatMagickString(filename,MaxTextExtent,"%s.log",basename); 00713 (void) remove(filename); 00714 if (coalesce_image != image) 00715 coalesce_image=DestroyImage(coalesce_image); 00716 if (image->debug != MagickFalse) 00717 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit"); 00718 return(status); 00719 }

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