static MagickBooleanType WriteMPEGImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { #define WriteMPEGIntermediateFormat "jpg" char basename[MagickPathExtent], filename[MagickPathExtent]; double delay; Image *coalesce_image; ImageInfo *write_info; int file; MagickBooleanType status; register Image *p; register ssize_t i; size_t count, length, scene; unsigned char *blob; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickCoreSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); (void) CloseBlob(image); /* Write intermediate files. */ coalesce_image=CoalesceImages(image,exception); if (coalesce_image == (Image *) NULL) return(MagickFalse); file=AcquireUniqueFileResource(basename); if (file != -1) file=close(file)-1; (void) FormatLocaleString(coalesce_image->filename,MagickPathExtent,"%s", basename); count=0; write_info=CloneImageInfo(image_info); *write_info->magick='\0'; for (p=coalesce_image; p != (Image *) NULL; p=GetNextImageInList(p)) { char previous_image[MagickPathExtent]; blob=(unsigned char *) NULL; length=0; scene=p->scene; delay=100.0*p->delay/MagickMax(1.0*p->ticks_per_second,1.0); for (i=0; i < (ssize_t) MagickMax((1.0*delay+1.0)/3.0,1.0); i++) { p->scene=count; count++; status=MagickFalse; switch (i) { case 0: { Image *frame; (void) FormatLocaleString(p->filename,MagickPathExtent,"%s%.20g.%s", basename,(double) p->scene,WriteMPEGIntermediateFormat); (void) FormatLocaleString(filename,MagickPathExtent,"%s%.20g.%s", basename,(double) p->scene,WriteMPEGIntermediateFormat); (void) FormatLocaleString(previous_image,MagickPathExtent, "%s%.20g.%s",basename,(double) p->scene, WriteMPEGIntermediateFormat); frame=CloneImage(p,0,0,MagickTrue,exception); if (frame == (Image *) NULL) break; status=WriteImage(write_info,frame,exception); frame=DestroyImage(frame); break; } case 1: { blob=(unsigned char *) FileToBlob(previous_image,~0UL,&length, exception); } default: { (void) FormatLocaleString(filename,MagickPathExtent,"%s%.20g.%s", basename,(double) p->scene,WriteMPEGIntermediateFormat); if (length > 0) status=BlobToFile(filename,blob,length,exception); break; } } if (image->debug != MagickFalse) { if (status != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "%.20g. Wrote %s file for scene %.20g:",(double) i, WriteMPEGIntermediateFormat,(double) p->scene); else (void) LogMagickEvent(CoderEvent,GetMagickModule(), "%.20g. Failed to write %s file for scene %.20g:",(double) i, WriteMPEGIntermediateFormat,(double) p->scene); (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%s",filename); } } p->scene=scene; if (blob != (unsigned char *) NULL) blob=(unsigned char *) RelinquishMagickMemory(blob); if (status == MagickFalse) break; } /* Convert JPEG to MPEG. */ (void) CopyMagickString(coalesce_image->magick_filename,basename, MagickPathExtent); (void) CopyMagickString(coalesce_image->filename,basename,MagickPathExtent); GetPathComponent(image_info->filename,ExtensionPath,coalesce_image->magick); if (*coalesce_image->magick == '\0') (void) CopyMagickString(coalesce_image->magick,image->magick, MagickPathExtent); status=InvokeDelegate(write_info,coalesce_image,(char *) NULL,"mpeg:encode", exception); (void) FormatLocaleString(write_info->filename,MagickPathExtent,"%s.%s", write_info->unique,coalesce_image->magick); status=CopyDelegateFile(write_info->filename,image->filename); (void) RelinquishUniqueFileResource(write_info->filename); write_info=DestroyImageInfo(write_info); /* Relinquish resources. */ count=0; for (p=coalesce_image; p != (Image *) NULL; p=GetNextImageInList(p)) { delay=100.0*p->delay/MagickMax(1.0*p->ticks_per_second,1.0); for (i=0; i < (ssize_t) MagickMax((1.0*delay+1.0)/3.0,1.0); i++) { (void) FormatLocaleString(p->filename,MagickPathExtent,"%s%.20g.%s", basename,(double) count++,WriteMPEGIntermediateFormat); (void) RelinquishUniqueFileResource(p->filename); } (void) CopyMagickString(p->filename,image_info->filename,MagickPathExtent); } (void) RelinquishUniqueFileResource(basename); coalesce_image=DestroyImageList(coalesce_image); if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit"); return(status); }
static MagickBooleanType WriteMPEGImage(const ImageInfo *image_info, Image *image) { char basename[MaxTextExtent], filename[MaxTextExtent]; Image *coalesce_image, *next_image; ImageInfo *write_info; int file; MagickBooleanType status; register Image *p; register long i; size_t length; unsigned char *blob; unsigned long count, delay, scene; /* Open output image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); if (status == MagickFalse) return(status); CloseBlob(image); /* Determine if the sequence of images have identical page info. */ coalesce_image=image; for (next_image=image; next_image != (Image *) NULL; ) { if ((image->columns != next_image->columns) || (image->rows != next_image->rows)) break; if ((image->page.x != next_image->page.x) || (image->page.y != next_image->page.y)) break; next_image=GetNextImageInList(next_image); } if (next_image != (Image *) NULL) { coalesce_image=CoalesceImages(image,&image->exception); if (coalesce_image == (Image *) NULL) return(MagickFalse); } /* Write YUV files. */ file=AcquireUniqueFileResource(basename); if (file != -1) file=close(file)-1; (void) FormatMagickString(coalesce_image->filename,MaxTextExtent,"%s", basename); write_info=CloneImageInfo(image_info); status=WriteMPEGParameterFiles(write_info,coalesce_image,basename); if (status == MagickFalse) { if (coalesce_image != image) coalesce_image=DestroyImage(coalesce_image); (void) remove(basename); if (image->quality != UndefinedCompressionQuality) { (void) FormatMagickString(filename,MaxTextExtent,"%s.iqm", basename); (void) remove(filename); (void) FormatMagickString(filename,MaxTextExtent,"%s.niq", basename); (void) remove(filename); } ThrowWriterException(CoderError,"UnableToWriteMPEGParameters"); } count=0; write_info->interlace=PlaneInterlace; for (p=coalesce_image; p != (Image *) NULL; p=GetNextImageInList(p)) { char previous_image[MaxTextExtent]; blob=(unsigned char *) NULL; length=0; scene=p->scene; delay=100*p->delay/Max(p->ticks_per_second,1); for (i=0; i < (long) Max((delay+1)/3,1); i++) { p->scene=count; count++; status=MagickFalse; switch (i) { case 0: { Image *frame; (void) FormatMagickString(p->filename,MaxTextExtent,"%s.%lu.yuv", basename,p->scene); (void) FormatMagickString(filename,MaxTextExtent,"%s.%lu.yuv", basename,p->scene); (void) FormatMagickString(previous_image,MaxTextExtent, "%s.%lu.yuv",basename,p->scene); frame=CloneImage(p,0,0,MagickTrue,&p->exception); if (frame == (Image *) NULL) break; status=WriteImage(write_info,frame); frame=DestroyImage(frame); break; } case 1: { blob=(unsigned char *) FileToBlob(previous_image,~0,&length,&image->exception); } default: { (void) FormatMagickString(filename,MaxTextExtent,"%s.%lu.yuv", basename,p->scene); if (length > 0) status=BlobToFile(filename,blob,length,&image->exception); break; } } if (image->debug != MagickFalse) { if (status != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "%lu. Wrote YUV file for scene %lu:",i,p->scene); else (void) LogMagickEvent(CoderEvent,GetMagickModule(), "%lu. Failed to write YUV file for scene %lu:",i,p->scene); (void) LogMagickEvent(CoderEvent,GetMagickModule(),"%s", filename); } } p->scene=scene; if (blob != (unsigned char *) NULL) blob=(unsigned char *) RelinquishMagickMemory(blob); if (status == MagickFalse) break; } /* Convert YUV to MPEG. */ (void) CopyMagickString(coalesce_image->filename,basename,MaxTextExtent); status=InvokeDelegate(write_info,coalesce_image,(char *) NULL,"mpeg-encode", &image->exception); write_info=DestroyImageInfo(write_info); /* Free resources. */ count=0; for (p=coalesce_image; p != (Image *) NULL; p=GetNextImageInList(p)) { delay=100*p->delay/Max(p->ticks_per_second,1); for (i=0; i < (long) Max((delay+1)/3,1); i++) { (void) FormatMagickString(p->filename,MaxTextExtent,"%s.%lu.yuv", basename,count++); (void) remove(p->filename); } (void) CopyMagickString(p->filename,image_info->filename,MaxTextExtent); } (void) RelinquishUniqueFileResource(basename); (void) FormatMagickString(filename,MaxTextExtent,"%s.iqm",basename); (void) remove(filename); (void) FormatMagickString(filename,MaxTextExtent,"%s.niq",basename); (void) remove(filename); (void) FormatMagickString(filename,MaxTextExtent,"%s.log",basename); (void) remove(filename); if (coalesce_image != image) coalesce_image=DestroyImage(coalesce_image); if (image->debug != MagickFalse) (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit"); return(status); }