/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + C L I C a t c h E x c e p t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % CLICatchException() will report exceptions, either just non-fatal warnings % only, or all errors, according to 'all_execeptions' boolean argument. % % The function returns true if errors are fatal, in which case the caller % should abort and re-call with an 'all_exceptions' argument of true before % quitting. % % The cut-off level between fatal and non-fatal may be controlled by options % (FUTURE), but defaults to 'Error' exceptions. % % The format of the CLICatchException method is: % % MagickBooleanType CLICatchException(MagickCLI *cli_wand, % const MagickBooleanType all_exceptions ); % % Arguments are % % o cli_wand: The Wand CLI that holds the exception Information % % o all_exceptions: Report all exceptions, including the fatal one % */ WandExport MagickBooleanType CLICatchException(MagickCLI *cli_wand, const MagickBooleanType all_exceptions ) { MagickBooleanType status; assert(cli_wand != (MagickCLI *) NULL); assert(cli_wand->signature == WandSignature); assert(cli_wand->wand.signature == WandSignature); if (IfMagickTrue(cli_wand->wand.debug)) (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); // FUTURE: '-regard_warning' should make this more sensitive. // Note pipelined options may like more control over this level status = IsMagickTrue(cli_wand->wand.exception->severity > ErrorException); if ( IfMagickFalse(status) || IfMagickTrue(all_exceptions) ) CatchException(cli_wand->wand.exception); /* output and clear exceptions */ return(status); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + D e s t r o y W a n d C L I % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DestroyMagickCLI() destorys everything in a CLI wand, including image_info % and any exceptions, if still present in the wand. % % The format of the NewMagickWand method is: % % MagickWand *DestroyMagickCLI() % Exception *exception) % */ WandExport MagickCLI *DestroyMagickCLI(MagickCLI *cli_wand) { Stack *node; assert(cli_wand != (MagickCLI *) NULL); assert(cli_wand->signature == WandSignature); assert(cli_wand->wand.signature == WandSignature); if (IfMagickTrue(cli_wand->wand.debug)) (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); /* Destroy CLI part of MagickCLI */ if (cli_wand->draw_info != (DrawInfo *) NULL ) cli_wand->draw_info=DestroyDrawInfo(cli_wand->draw_info); if (cli_wand->quantize_info != (QuantizeInfo *) NULL ) cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info); while(cli_wand->image_list_stack != (Stack *)NULL) { node=cli_wand->image_list_stack; cli_wand->image_list_stack=node->next; (void) DestroyImageList((Image *)node->data); (void) RelinquishMagickMemory(node); } while(cli_wand->image_info_stack != (Stack *)NULL) { node=cli_wand->image_info_stack; cli_wand->image_info_stack=node->next; (void) DestroyImageInfo((ImageInfo *)node->data); (void) RelinquishMagickMemory(node); } cli_wand->signature=(~WandSignature); /* Destroy Wand part MagickCLI */ cli_wand->wand.images=DestroyImageList(cli_wand->wand.images); if (cli_wand->wand.image_info != (ImageInfo *) NULL ) cli_wand->wand.image_info=DestroyImageInfo(cli_wand->wand.image_info); if (cli_wand->wand.exception != (ExceptionInfo *) NULL ) cli_wand->wand.exception=DestroyExceptionInfo(cli_wand->wand.exception); RelinquishWandId(cli_wand->wand.id); cli_wand->wand.signature=(~WandSignature); return((MagickCLI *)NULL); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d P A N G O I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadPANGOImage() reads an image in the Pango Markup Language Format. % % The format of the ReadPANGOImage method is: % % Image *ReadPANGOImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadPANGOImage(const ImageInfo *image_info, ExceptionInfo *exception) { cairo_font_options_t *font_options; cairo_surface_t *surface; char *caption, *property; cairo_t *cairo_image; const char *option; DrawInfo *draw_info; Image *image; MagickBooleanType status; PangoAlignment align; PangoContext *context; PangoFontMap *fontmap; PangoGravity gravity; PangoLayout *layout; PangoRectangle extent; PixelInfo fill_color; RectangleInfo page; register unsigned char *p; size_t stride; ssize_t y; unsigned char *pixels; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info,exception); (void) ResetImagePage(image,"0x0+0+0"); /* Format caption. */ option=GetImageArtifact(image,"filename"); if (option == (const char *) NULL) property=InterpretImageProperties(image_info,image,image_info->filename, exception); else if (LocaleNCompare(option,"pango:",6) == 0) property=InterpretImageProperties(image_info,image,option+6,exception); else property=InterpretImageProperties(image_info,image,option,exception); (void) SetImageProperty(image,"caption",property,exception); property=DestroyString(property); caption=ConstantString(GetImageProperty(image,"caption",exception)); /* Get context. */ fontmap=pango_cairo_font_map_new(); pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap), image->resolution.x == 0.0 ? 90.0 : image->resolution.x); font_options=cairo_font_options_create(); option=GetImageArtifact(image,"pango:hinting"); if (option != (const char *) NULL) { if (LocaleCompare(option,"none") != 0) cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_NONE); if (LocaleCompare(option,"full") != 0) cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_FULL); } context=pango_font_map_create_context(fontmap); pango_cairo_context_set_font_options(context,font_options); cairo_font_options_destroy(font_options); option=GetImageArtifact(image,"pango:language"); if (option != (const char *) NULL) pango_context_set_language(context,pango_language_from_string(option)); draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL); pango_context_set_base_dir(context,draw_info->direction == RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR); switch (draw_info->gravity) { case NorthGravity: { gravity=PANGO_GRAVITY_NORTH; break; } case NorthWestGravity: case WestGravity: case SouthWestGravity: { gravity=PANGO_GRAVITY_WEST; break; } case NorthEastGravity: case EastGravity: case SouthEastGravity: { gravity=PANGO_GRAVITY_EAST; break; } case SouthGravity: { gravity=PANGO_GRAVITY_SOUTH; break; } default: { gravity=PANGO_GRAVITY_AUTO; break; } } pango_context_set_base_gravity(context,gravity); option=GetImageArtifact(image,"pango:gravity-hint"); if (option != (const char *) NULL) { if (LocaleCompare(option,"line") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_LINE); if (LocaleCompare(option,"natural") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_NATURAL); if (LocaleCompare(option,"strong") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_STRONG); } /* Configure layout. */ layout=pango_layout_new(context); option=GetImageArtifact(image,"pango:auto-dir"); if (option != (const char *) NULL) pango_layout_set_auto_dir(layout,1); option=GetImageArtifact(image,"pango:ellipsize"); if (option != (const char *) NULL) { if (LocaleCompare(option,"end") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_END); if (LocaleCompare(option,"middle") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_MIDDLE); if (LocaleCompare(option,"none") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_NONE); if (LocaleCompare(option,"start") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START); } option=GetImageArtifact(image,"pango:justify"); if (IfMagickTrue(IsStringTrue(option))) pango_layout_set_justify(layout,1); option=GetImageArtifact(image,"pango:single-paragraph"); if (IfMagickTrue(IsStringTrue(option))) pango_layout_set_single_paragraph_mode(layout,1); option=GetImageArtifact(image,"pango:wrap"); if (option != (const char *) NULL) { if (LocaleCompare(option,"char") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_CHAR); if (LocaleCompare(option,"word") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_WORD); if (LocaleCompare(option,"word-char") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR); } option=GetImageArtifact(image,"pango:indent"); if (option != (const char *) NULL) pango_layout_set_indent(layout,(int) ((StringToLong(option)* (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)*PANGO_SCALE+36)/ 90.0+0.5)); switch (draw_info->align) { case CenterAlign: align=PANGO_ALIGN_CENTER; break; case RightAlign: align=PANGO_ALIGN_RIGHT; break; case LeftAlign: align=PANGO_ALIGN_LEFT; break; default: { if (draw_info->gravity == CenterGravity) { align=PANGO_ALIGN_CENTER; break; } align=PANGO_ALIGN_LEFT; break; } } if ((align != PANGO_ALIGN_CENTER) && (draw_info->direction == RightToLeftDirection)) align=(PangoAlignment) (PANGO_ALIGN_LEFT+PANGO_ALIGN_RIGHT-align); pango_layout_set_alignment(layout,align); if (draw_info->font != (char *) NULL) { PangoFontDescription *description; /* Set font. */ description=pango_font_description_from_string(draw_info->font); pango_font_description_set_size(description,(int) (PANGO_SCALE* draw_info->pointsize+0.5)); pango_layout_set_font_description(layout,description); pango_font_description_free(description); } option=GetImageArtifact(image,"pango:markup"); if ((option != (const char *) NULL) && (IsStringTrue(option) == MagickFalse)) pango_layout_set_text(layout,caption,-1); else { GError *error; error=(GError *) NULL; if (pango_parse_markup(caption,-1,0,NULL,NULL,NULL,&error) == 0) (void) ThrowMagickException(exception,GetMagickModule(),CoderError, error->message,"`%s'",image_info->filename); pango_layout_set_markup(layout,caption,-1); } pango_layout_context_changed(layout); page.x=0; page.y=0; if (image_info->page != (char *) NULL) (void) ParseAbsoluteGeometry(image_info->page,&page); if (image->columns == 0) { pango_layout_get_extents(layout,NULL,&extent); image->columns=(extent.x+extent.width+PANGO_SCALE/2)/PANGO_SCALE+2*page.x; } else { image->columns-=2*page.x; pango_layout_set_width(layout,(int) ((PANGO_SCALE*image->columns* (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)+45.0)/90.0+ 0.5)); } if (image->rows == 0) { pango_layout_get_extents(layout,NULL,&extent); image->rows=(extent.y+extent.height+PANGO_SCALE/2)/PANGO_SCALE+2*page.y; } else { image->rows-=2*page.y; pango_layout_set_height(layout,(int) ((PANGO_SCALE*image->rows* (image->resolution.y == 0.0 ? 90.0 : image->resolution.y)+45.0)/90.0+ 0.5)); } /* Render markup. */ stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, image->columns); pixels=(unsigned char *) AcquireQuantumMemory(image->rows,stride* sizeof(*pixels)); if (pixels == (unsigned char *) NULL) { draw_info=DestroyDrawInfo(draw_info); caption=DestroyString(caption); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } surface=cairo_image_surface_create_for_data(pixels,CAIRO_FORMAT_ARGB32, image->columns,image->rows,stride); cairo_image=cairo_create(surface); cairo_set_operator(cairo_image,CAIRO_OPERATOR_CLEAR); cairo_paint(cairo_image); cairo_set_operator(cairo_image,CAIRO_OPERATOR_OVER); cairo_translate(cairo_image,page.x,page.y); pango_cairo_show_layout(cairo_image,layout); cairo_destroy(cairo_image); cairo_surface_destroy(surface); g_object_unref(layout); g_object_unref(fontmap); /* Convert surface to image. */ (void) SetImageBackgroundColor(image,exception); p=pixels; GetPixelInfo(image,&fill_color); for (y=0; y < (ssize_t) image->rows; y++) { register Quantum *q; register ssize_t x; q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { double gamma; fill_color.blue=(double) ScaleCharToQuantum(*p++); fill_color.green=(double) ScaleCharToQuantum(*p++); fill_color.red=(double) ScaleCharToQuantum(*p++); fill_color.alpha=(double) ScaleCharToQuantum(*p++); /* Disassociate alpha. */ gamma=1.0-QuantumScale*fill_color.alpha; gamma=PerceptibleReciprocal(gamma); fill_color.blue*=gamma; fill_color.green*=gamma; fill_color.red*=gamma; CompositePixelOver(image,&fill_color,fill_color.alpha,q,(double) GetPixelAlpha(image,q),q); q+=GetPixelChannels(image); } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } /* Relinquish resources. */ pixels=(unsigned char *) RelinquishMagickMemory(pixels); draw_info=DestroyDrawInfo(draw_info); caption=DestroyString(caption); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + A c q u i r e W a n d C L I % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % AcquireMagickCLI() creates a new CLI wand (an expanded form of Magick % Wand). The given image_info and exception is included as is if provided. % % Use DestroyMagickCLI() to dispose of the CLI wand when it is no longer % needed. % % The format of the NewMagickWand method is: % % MagickCLI *AcquireMagickCLI(ImageInfo *image_info, % ExceptionInfo *exception) % */ WandExport MagickCLI *AcquireMagickCLI(ImageInfo *image_info, ExceptionInfo *exception) { MagickCLI *cli_wand; /* precaution - as per NewMagickWand() */ { size_t depth = MAGICKCORE_QUANTUM_DEPTH; const char *quantum = GetMagickQuantumDepth(&depth); if (depth != MAGICKCORE_QUANTUM_DEPTH) ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum); } /* allocate memory for MgaickCLI */ cli_wand=(MagickCLI *) AcquireMagickMemory(sizeof(*cli_wand)); if (cli_wand == (MagickCLI *) NULL) { ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed", GetExceptionMessage(errno)); return((MagickCLI *)NULL); } /* Initialize Wand Part of MagickCLI FUTURE: this is a repeat of code from NewMagickWand() However some parts may be given fro man external source! */ cli_wand->wand.id=AcquireWandId(); (void) FormatLocaleString(cli_wand->wand.name,MaxTextExtent, "%s-%.20g","MagickWandCLI", (double) cli_wand->wand.id); cli_wand->wand.images=NewImageList(); if ( image_info == (ImageInfo *)NULL) cli_wand->wand.image_info=AcquireImageInfo(); else cli_wand->wand.image_info=image_info; if ( exception == (ExceptionInfo *)NULL) cli_wand->wand.exception=AcquireExceptionInfo(); else cli_wand->wand.exception=exception; cli_wand->wand.debug=IsEventLogging(); cli_wand->wand.signature=WandSignature; /* Initialize CLI Part of MagickCLI */ cli_wand->draw_info=CloneDrawInfo(cli_wand->wand.image_info,(DrawInfo *) NULL); cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info); cli_wand->process_flags=MagickCommandOptionFlags; /* assume "magick" CLI */ cli_wand->command=(const OptionInfo *)NULL; /* no option at this time */ cli_wand->image_list_stack=(Stack *)NULL; cli_wand->image_info_stack=(Stack *)NULL; /* default exception location... EG: sprintf(locaiton, filename, line, column); */ cli_wand->location="from \"%s\""; /* location format using arguments: */ /* filename, line, column */ cli_wand->filename="unknown"; /* script filename, unknown source */ cli_wand->line=0; /* line from script OR CLI argument */ cli_wand->column=0; /* column from script */ cli_wand->signature=WandSignature; if (IfMagickTrue(cli_wand->wand.debug)) (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name); return(cli_wand); }
static MagickBooleanType WritePCLImage(const ImageInfo *image_info,Image *image, ExceptionInfo *exception) { char buffer[MaxTextExtent]; const char *option; MagickBooleanType status; MagickOffsetType scene; register const Quantum *p; register ssize_t i, x; register unsigned char *q; size_t density, length, one, packets; ssize_t y; unsigned char bits_per_pixel, *compress_pixels, *pixels, *previous_pixels; /* 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); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); density=75; if (image_info->density != (char *) NULL) { GeometryInfo geometry; (void) ParseGeometry(image_info->density,&geometry); density=(size_t) geometry.rho; } scene=0; one=1; do { if (IsRGBColorspace(image->colorspace) == MagickFalse) (void) TransformImageColorspace(image,sRGBColorspace,exception); /* Initialize the printer. */ (void) WriteBlobString(image,"\033E"); /* printer reset */ (void) WriteBlobString(image,"\033*r3F"); /* set presentation mode */ (void) FormatLocaleString(buffer,MaxTextExtent,"\033*r%.20gs%.20gT", (double) image->columns,(double) image->rows); (void) WriteBlobString(image,buffer); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*t%.20gR",(double) density); (void) WriteBlobString(image,buffer); (void) WriteBlobString(image,"\033&l0E"); /* top margin 0 */ if (IsImageMonochrome(image,exception) != MagickFalse) { /* Monochrome image: use default printer monochrome setup. */ bits_per_pixel=1; } else if (image->storage_class == DirectClass) { /* DirectClass image. */ bits_per_pixel=24; (void) WriteBlobString(image,"\033*v6W"); /* set color mode */ (void) WriteBlobByte(image,0); /* RGB */ (void) WriteBlobByte(image,3); /* direct by pixel */ (void) WriteBlobByte(image,0); /* bits per index (ignored) */ (void) WriteBlobByte(image,8); /* bits per red component */ (void) WriteBlobByte(image,8); /* bits per green component */ (void) WriteBlobByte(image,8); /* bits per blue component */ } else { /* Colormapped image. */ bits_per_pixel=8; (void) WriteBlobString(image,"\033*v6W"); /* set color mode... */ (void) WriteBlobByte(image,0); /* RGB */ (void) WriteBlobByte(image,1); /* indexed by pixel */ (void) WriteBlobByte(image,bits_per_pixel); /* bits per index */ (void) WriteBlobByte(image,8); /* bits per red component */ (void) WriteBlobByte(image,8); /* bits per green component */ (void) WriteBlobByte(image,8); /* bits per blue component */ for (i=0; i < (ssize_t) image->colors; i++) { (void) FormatLocaleString(buffer,MaxTextExtent, "\033*v%da%db%dc%.20gI", ScaleQuantumToChar(image->colormap[i].red), ScaleQuantumToChar(image->colormap[i].green), ScaleQuantumToChar(image->colormap[i].blue),(double) i); (void) WriteBlobString(image,buffer); } for (one=1; i < (ssize_t) (one << bits_per_pixel); i++) { (void) FormatLocaleString(buffer,MaxTextExtent,"\033*v%.20gI", (double) i); (void) WriteBlobString(image,buffer); } } option=GetImageOption(image_info,"pcl:fit-to-page"); if (IfMagickTrue(IsStringTrue(option))) (void) WriteBlobString(image,"\033*r3A"); else (void) WriteBlobString(image,"\033*r1A"); /* start raster graphics */ (void) WriteBlobString(image,"\033*b0Y"); /* set y offset */ length=(image->columns*bits_per_pixel+7)/8; pixels=(unsigned char *) AcquireQuantumMemory(length+1,sizeof(*pixels)); if (pixels == (unsigned char *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); (void) ResetMagickMemory(pixels,0,(length+1)*sizeof(*pixels)); compress_pixels=(unsigned char *) NULL; previous_pixels=(unsigned char *) NULL; switch (image->compression) { case NoCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b0M"); (void) WriteBlobString(image,buffer); break; } case RLECompression: { compress_pixels=(unsigned char *) AcquireQuantumMemory(length+256, sizeof(*compress_pixels)); if (compress_pixels == (unsigned char *) NULL) { pixels=(unsigned char *) RelinquishMagickMemory(pixels); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } (void) ResetMagickMemory(compress_pixels,0,(length+256)* sizeof(*compress_pixels)); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b2M"); (void) WriteBlobString(image,buffer); break; } default: { compress_pixels=(unsigned char *) AcquireQuantumMemory(3*length+256, sizeof(*compress_pixels)); if (compress_pixels == (unsigned char *) NULL) { pixels=(unsigned char *) RelinquishMagickMemory(pixels); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } (void) ResetMagickMemory(compress_pixels,0,(3*length+256)* sizeof(*compress_pixels)); previous_pixels=(unsigned char *) AcquireQuantumMemory(length+1, sizeof(*previous_pixels)); if (previous_pixels == (unsigned char *) NULL) { compress_pixels=(unsigned char *) RelinquishMagickMemory( compress_pixels); pixels=(unsigned char *) RelinquishMagickMemory(pixels); ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); } (void) ResetMagickMemory(previous_pixels,0,(length+1)* sizeof(*previous_pixels)); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b3M"); (void) WriteBlobString(image,buffer); break; } } for (y=0; y < (ssize_t) image->rows; y++) { p=GetVirtualPixels(image,0,y,image->columns,1,exception); if (p == (const Quantum *) NULL) break; q=pixels; switch (bits_per_pixel) { case 1: { register unsigned char bit, byte; /* Monochrome image. */ bit=0; byte=0; for (x=0; x < (ssize_t) image->columns; x++) { byte<<=1; if (GetPixelIntensity(image,p) < ((MagickRealType) QuantumRange/2.0)) byte|=0x01; bit++; if (bit == 8) { *q++=byte; bit=0; byte=0; } p+=GetPixelChannels(image); } if (bit != 0) *q++=byte << (8-bit); break; } case 8: { /* Colormapped image. */ for (x=0; x < (ssize_t) image->columns; x++) { *q++=(unsigned char) GetPixelIndex(image,p); p+=GetPixelChannels(image); } break; } case 24: case 32: { /* Truecolor image. */ for (x=0; x < (ssize_t) image->columns; x++) { *q++=ScaleQuantumToChar(GetPixelRed(image,p)); *q++=ScaleQuantumToChar(GetPixelGreen(image,p)); *q++=ScaleQuantumToChar(GetPixelBlue(image,p)); p+=GetPixelChannels(image); } break; } } switch (image->compression) { case NoCompression: { (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b%.20gW", (double) length); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,length,pixels); break; } case RLECompression: { packets=PCLPackbitsCompressImage(length,pixels,compress_pixels); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b%.20gW", (double) packets); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,packets,compress_pixels); break; } default: { if (y == 0) for (i=0; i < (ssize_t) length; i++) previous_pixels[i]=(~pixels[i]); packets=PCLDeltaCompressImage(length,previous_pixels,pixels, compress_pixels); (void) FormatLocaleString(buffer,MaxTextExtent,"\033*b%.20gW", (double) packets); (void) WriteBlobString(image,buffer); (void) WriteBlob(image,packets,compress_pixels); (void) CopyMagickMemory(previous_pixels,pixels,length* sizeof(*pixels)); break; } } } (void) WriteBlobString(image,"\033*rB"); /* end graphics */ switch (image->compression) { case NoCompression: break; case RLECompression: { compress_pixels=(unsigned char *) RelinquishMagickMemory( compress_pixels); break; } default: { previous_pixels=(unsigned char *) RelinquishMagickMemory( previous_pixels); compress_pixels=(unsigned char *) RelinquishMagickMemory( compress_pixels); break; } } pixels=(unsigned char *) RelinquishMagickMemory(pixels); if (GetNextImageInList(image) == (Image *) NULL) break; image=SyncNextImageInList(image); status=SetImageProgress(image,SaveImagesTag,scene++, GetImageListLength(image)); if (status == MagickFalse) break; } while (image_info->adjoin != MagickFalse); (void) WriteBlobString(image,"\033E"); (void) CloseBlob(image); return(MagickTrue); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % W r i t e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % WriteImage() writes an image or an image sequence to a file or file handle. % If writing to a file is on disk, the name is defined by the filename member % of the image structure. WriteImage() returns MagickFalse is there is a % memory shortage or if the image cannot be written. Check the exception % member of image to determine the cause for any failure. % % The format of the WriteImage method is: % % MagickBooleanType WriteImage(const ImageInfo *image_info,Image *image, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o image: the image. % % o exception: return any errors or warnings in this structure. % */ MagickExport MagickBooleanType WriteImage(const ImageInfo *image_info, Image *image,ExceptionInfo *exception) { char filename[MaxTextExtent]; const char *option; const DelegateInfo *delegate_info; const MagickInfo *magick_info; ExceptionInfo *sans_exception; ImageInfo *write_info; MagickBooleanType status, temporary; MagickStatusType thread_support; PolicyDomain domain; PolicyRights rights; /* Determine image type from filename prefix or suffix (e.g. image.jpg). */ assert(image_info != (ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(image != (Image *) NULL); assert(image->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); sans_exception=AcquireExceptionInfo(); write_info=CloneImageInfo(image_info); (void) CopyMagickString(write_info->filename,image->filename,MaxTextExtent); if (*write_info->magick == '\0') (void) CopyMagickString(write_info->magick,image->magick,MaxTextExtent); (void) SetImageInfo(write_info,1,sans_exception); (void) CopyMagickString(filename,image->filename,MaxTextExtent); (void) CopyMagickString(image->filename,write_info->filename,MaxTextExtent); domain=CoderPolicyDomain; rights=WritePolicyRights; if (IsRightsAuthorized(domain,rights,write_info->magick) == MagickFalse) { sans_exception=DestroyExceptionInfo(sans_exception); write_info=DestroyImageInfo(write_info); errno=EPERM; ThrowBinaryException(PolicyError,"NotAuthorized",filename); } /* Call appropriate image reader based on image type. */ magick_info=GetMagickInfo(write_info->magick,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (magick_info != (const MagickInfo *) NULL) { if (GetMagickEndianSupport(magick_info) == MagickFalse) image->endian=UndefinedEndian; else if ((image_info->endian == UndefinedEndian) && (GetMagickRawSupport(magick_info) != MagickFalse)) { size_t lsb_first; lsb_first=1; image->endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian; } } (void) SyncImageProfiles(image); DisassociateImageStream(image); option=GetImageOption(image_info,"delegate:bimodal"); if ((IfMagickTrue(IsStringTrue(option))) && (write_info->page == (char *) NULL) && (GetPreviousImageInList(image) == (Image *) NULL) && (GetNextImageInList(image) == (Image *) NULL) && (IfMagickFalse(IsTaintImage(image))) ) { delegate_info=GetDelegateInfo(image->magick,write_info->magick,exception); if ((delegate_info != (const DelegateInfo *) NULL) && (GetDelegateMode(delegate_info) == 0) && (IsPathAccessible(image->magick_filename) != MagickFalse)) { /* Process image with bi-modal delegate. */ (void) CopyMagickString(image->filename,image->magick_filename, MaxTextExtent); status=InvokeDelegate(write_info,image,image->magick, write_info->magick,exception); write_info=DestroyImageInfo(write_info); (void) CopyMagickString(image->filename,filename,MaxTextExtent); return(status); } } status=MagickFalse; temporary=MagickFalse; if ((magick_info != (const MagickInfo *) NULL) && (GetMagickSeekableStream(magick_info) != MagickFalse)) { char filename[MaxTextExtent]; (void) CopyMagickString(filename,image->filename,MaxTextExtent); status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); (void) CopyMagickString(image->filename,filename,MaxTextExtent); if (status != MagickFalse) { if (IsBlobSeekable(image) == MagickFalse) { /* A seekable stream is required by the encoder. */ write_info->adjoin=MagickTrue; (void) CopyMagickString(write_info->filename,image->filename, MaxTextExtent); (void) AcquireUniqueFilename(image->filename); temporary=MagickTrue; } (void) CloseBlob(image); } } if ((magick_info != (const MagickInfo *) NULL) && (GetImageEncoder(magick_info) != (EncodeImageHandler *) NULL)) { /* Call appropriate image writer based on image type. */ thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & EncoderThreadSupport) == 0) LockSemaphoreInfo(magick_info->semaphore); status=GetImageEncoder(magick_info)(write_info,image,exception); if ((thread_support & EncoderThreadSupport) == 0) UnlockSemaphoreInfo(magick_info->semaphore); } else { delegate_info=GetDelegateInfo((char *) NULL,write_info->magick,exception); if (delegate_info != (DelegateInfo *) NULL) { /* Process the image with delegate. */ *write_info->filename='\0'; if (GetDelegateThreadSupport(delegate_info) == MagickFalse) LockSemaphoreInfo(delegate_info->semaphore); status=InvokeDelegate(write_info,image,(char *) NULL, write_info->magick,exception); if (GetDelegateThreadSupport(delegate_info) == MagickFalse) UnlockSemaphoreInfo(delegate_info->semaphore); (void) CopyMagickString(image->filename,filename,MaxTextExtent); } else { sans_exception=AcquireExceptionInfo(); magick_info=GetMagickInfo(write_info->magick,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if ((write_info->affirm == MagickFalse) && (magick_info == (const MagickInfo *) NULL)) { (void) CopyMagickString(write_info->magick,image->magick, MaxTextExtent); magick_info=GetMagickInfo(write_info->magick,exception); } if ((magick_info == (const MagickInfo *) NULL) || (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL)) { char extension[MaxTextExtent]; GetPathComponent(image->filename,ExtensionPath,extension); if (*extension != '\0') magick_info=GetMagickInfo(extension,exception); else magick_info=GetMagickInfo(image->magick,exception); (void) CopyMagickString(image->filename,filename,MaxTextExtent); } if ((magick_info == (const MagickInfo *) NULL) || (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL)) { magick_info=GetMagickInfo(image->magick,exception); if ((magick_info == (const MagickInfo *) NULL) || (GetImageEncoder(magick_info) == (EncodeImageHandler *) NULL)) (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateError,"NoEncodeDelegateForThisImageFormat", "`%s'",write_info->magick); else (void) ThrowMagickException(exception,GetMagickModule(), MissingDelegateWarning,"NoEncodeDelegateForThisImageFormat", "`%s'",write_info->magick); } if ((magick_info != (const MagickInfo *) NULL) && (GetImageEncoder(magick_info) != (EncodeImageHandler *) NULL)) { /* Call appropriate image writer based on image type. */ thread_support=GetMagickThreadSupport(magick_info); if ((thread_support & EncoderThreadSupport) == 0) LockSemaphoreInfo(magick_info->semaphore); status=GetImageEncoder(magick_info)(write_info,image,exception); if ((thread_support & EncoderThreadSupport) == 0) UnlockSemaphoreInfo(magick_info->semaphore); } } } if (GetBlobError(image) != MagickFalse) ThrowFileException(exception,FileOpenError, "AnErrorHasOccurredWritingToFile",image->filename); if (temporary != MagickFalse) { /* Copy temporary image file to permanent. */ status=OpenBlob(write_info,image,ReadBinaryBlobMode,exception); if (status != MagickFalse) { (void) RelinquishUniqueFileResource(write_info->filename); status=ImageToFile(image,write_info->filename,exception); } (void) CloseBlob(image); (void) RelinquishUniqueFileResource(image->filename); (void) CopyMagickString(image->filename,write_info->filename, MaxTextExtent); } if ((LocaleCompare(write_info->magick,"info") != 0) && (write_info->verbose != MagickFalse)) (void) IdentifyImage(image,stdout,MagickFalse,exception); write_info=DestroyImageInfo(write_info); return(status); }
WandExport MagickBooleanType MagickImageCommand(ImageInfo *image_info,int argc, char **argv,char **metadata,ExceptionInfo *exception) { MagickCLI *cli_wand; size_t len; assert(image_info != (ImageInfo *) NULL); /* For specific OS command line requirements */ ReadCommandlLine(argc,&argv); /* Initialize special "CLI Wand" to hold images and settings (empty) */ cli_wand=AcquireMagickCLI(image_info,exception); cli_wand->location="Initializing"; cli_wand->filename=argv[0]; cli_wand->line=1; if (IfMagickTrue(cli_wand->wand.debug)) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "\"%s\"",argv[0]); GetPathComponent(argv[0],TailPath,cli_wand->wand.name); SetClientName(cli_wand->wand.name); ConcatenateMagickString(cli_wand->wand.name,"-CLI",MagickPathExtent); len=strlen(argv[0]); /* precaution */ /* "convert" command - give a "deprecated" warning" */ if (len>=7 && LocaleCompare("convert",argv[0]+len-7) == 0) { cli_wand->process_flags = ConvertCommandOptionFlags; (void) FormatLocaleFile(stderr,"WARNING: %s\n", "The convert command is deprecated in IMv7, use \"magick\"\n"); } /* Special Case: If command name ends with "script" implied "-script" */ if (len>=6 && LocaleCompare("script",argv[0]+len-6) == 0) { if (argc >= 2 && ( (*(argv[1]) != '-') || (strlen(argv[1]) == 1) )) { GetPathComponent(argv[1],TailPath,cli_wand->wand.name); ProcessScriptOptions(cli_wand,argv[1],argc,argv,2); goto Magick_Command_Cleanup; } } /* Special Case: Version Information and Abort */ if (argc == 2) { if ((LocaleCompare("-version",argv[1]) == 0) || /* GNU standard option */ (LocaleCompare("--version",argv[1]) == 0) ) { /* just version */ CLIOption(cli_wand, "-version"); goto Magick_Command_Exit; } if ((LocaleCompare("-help",argv[1]) == 0) || /* GNU standard option */ (LocaleCompare("--help",argv[1]) == 0) ) { /* just a brief summary */ if (IfMagickTrue(cli_wand->wand.debug)) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "- Special Option \"%s\"", argv[1]); MagickUsage(MagickFalse); goto Magick_Command_Exit; } if (LocaleCompare("-usage",argv[1]) == 0) { /* both version & usage */ if (IfMagickTrue(cli_wand->wand.debug)) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "- Special Option \"%s\"", argv[1]); CLIOption(cli_wand, "-version" ); MagickUsage(MagickTrue); goto Magick_Command_Exit; } } /* not enough arguments -- including -help */ if (argc < 3) { (void) FormatLocaleFile(stderr, "Error: Invalid argument or not enough arguments\n\n"); MagickUsage(MagickFalse); goto Magick_Command_Exit; } /* Special "concatenate option (hidden) for delegate usage */ if (LocaleCompare("-concatenate",argv[1]) == 0) { if (IfMagickTrue(cli_wand->wand.debug)) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "- Special Option \"%s\"", argv[1]); ConcatenateImages(argc,argv,exception); goto Magick_Command_Exit; } /* List Information and Abort */ if (argc == 3 && LocaleCompare("-list",argv[1]) == 0) { CLIOption(cli_wand, argv[1], argv[2]); goto Magick_Command_Exit; } /* ------------- */ /* The Main Call */ if (LocaleCompare("-script",argv[1]) == 0) { /* Start processing directly from script, no pre-script options Replace wand command name with script name First argument in the argv array is the script name to read. */ GetPathComponent(argv[2],TailPath,cli_wand->wand.name); ProcessScriptOptions(cli_wand,argv[2],argc,argv,3); } else { /* Normal Command Line, assumes output file as last option */ ProcessCommandOptions(cli_wand,argc,argv,1); } /* ------------- */ Magick_Command_Cleanup: cli_wand->location="Cleanup"; cli_wand->filename=argv[0]; if (IfMagickTrue(cli_wand->wand.debug)) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "\"%s\"",argv[0]); /* recover original image_info and clean up stacks FUTURE: "-reset stacks" option */ while (cli_wand->image_list_stack != (Stack *) NULL) CLIOption(cli_wand,")"); while (cli_wand->image_info_stack != (Stack *) NULL) CLIOption(cli_wand,"}"); /* assert we have recovered the original structures */ assert(cli_wand->wand.image_info == image_info); assert(cli_wand->wand.exception == exception); /* Handle metadata for ImageMagickObject COM object for Windows VBS */ if (metadata != (char **) NULL) { const char *format; char *text; format="%w,%h,%m"; // Get this from image_info Option splaytree text=InterpretImageProperties(image_info,cli_wand->wand.images,format, exception); if (text == (char *) NULL) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError, "MemoryAllocationFailed","`%s'", GetExceptionMessage(errno)); else { (void) ConcatenateString(&(*metadata),text); text=DestroyString(text); } } Magick_Command_Exit: cli_wand->location="Exiting"; cli_wand->filename=argv[0]; if (IfMagickTrue(cli_wand->wand.debug)) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "\"%s\"",argv[0]); /* Destroy the special CLI Wand */ cli_wand->wand.image_info = (ImageInfo *) NULL; /* not these */ cli_wand->wand.exception = (ExceptionInfo *) NULL; cli_wand=DestroyMagickCLI(cli_wand); return(IsMagickTrue(exception->severity < ErrorException)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + P r o c e s s C o m m a n d O p t i o n s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ProcessCommandOptions() reads and processes arguments in the given % command line argument array. The 'index' defines where in the array we % should begin processing % % The 'process_flags' can be used to control and limit option processing. % For example, to only process one option, or how unknown and special options % are to be handled, and if the last argument in array is to be regarded as a % final image write argument (filename or special coder). % % The format of the ProcessCommandOptions method is: % % int ProcessCommandOptions(MagickCLI *cli_wand,int argc,char **argv, % int index) % % A description of each parameter follows: % % o cli_wand: the main CLI Wand to use. % % o argc: the number of elements in the argument vector. % % o argv: A text array containing the command line arguments. % % o process_flags: What type of arguments will be processed, ignored % or return errors. % % o index: index in the argv array to start processing from % % The function returns the index ot the next option to be processed. This % is really only releven if process_flags contains a ProcessOneOptionOnly % flag. % */ WandExport int ProcessCommandOptions(MagickCLI *cli_wand,int argc,char **argv, int index) { const char *option, *arg1, *arg2; int i, end, count; CommandOptionFlags option_type; assert(argc>=index); /* you may have no arguments left! */ assert(argv != (char **) NULL); assert(argv[index] != (char *) NULL); assert(argv[argc-1] != (char *) NULL); assert(cli_wand != (MagickCLI *) NULL); assert(cli_wand->signature == WandSignature); /* define the error location string for use in exceptions order of localtion format escapes: filename, line, column */ cli_wand->location="at %s arg %u"; cli_wand->filename="CLI"; cli_wand->line=index; /* note first argument we will process */ if (IfMagickTrue(cli_wand->wand.debug)) (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(), "- Starting (\"%s\")", argv[index]); end = argc; if ( (cli_wand->process_flags & ProcessImplictWrite) != 0 ) end--; /* the last arument is an implied write, do not process directly */ for (i=index; i < end; i += count +1) { /* Finished processing one option? */ if ( (cli_wand->process_flags & ProcessOneOptionOnly) != 0 && i != index ) return(i); do { /* use break to loop to exception handler and loop */ option=argv[i]; cli_wand->line=i; /* note the argument for this option */ /* get option, its argument count, and option type */ cli_wand->command = GetCommandOptionInfo(argv[i]); count=cli_wand->command->type; option_type=(CommandOptionFlags) cli_wand->command->flags; #if 0 (void) FormatLocaleFile(stderr, "CLI %d: \"%s\" matched \"%s\"\n", i, argv[i], cli_wand->command->mnemonic ); #endif if ( option_type == UndefinedOptionFlag || (option_type & NonMagickOptionFlag) != 0 ) { #if MagickCommandDebug >= 3 (void) FormatLocaleFile(stderr, "CLI arg %d Non-Option: \"%s\"\n", i, option); #endif if ( IfMagickFalse(IsCommandOption(option)) ) { if ( (cli_wand->process_flags & ProcessImplictRead) != 0 ) { /* non-option -- treat as a image read */ cli_wand->command=(const OptionInfo *) NULL; CLIOption(cli_wand,"-read",option); break; /* next option */ } } CLIWandException(OptionFatalError,"UnrecognizedOption",option); break; /* next option */ } if ( ((option_type & SpecialOptionFlag) != 0 ) && ((cli_wand->process_flags & ProcessScriptOption) != 0) && (LocaleCompare(option,"-script") == 0) ) { /* Call Script from CLI, with a filename as a zeroth argument. NOTE: -script may need to use the 'implict write filename' argument so it must be handled specially to prevent a 'missing argument' error. */ if ( (i+count) >= argc ) CLIWandException(OptionFatalError,"MissingArgument",option); ProcessScriptOptions(cli_wand,argv[i+1],argc,argv,i+count); return(argc); /* Script does not return to CLI -- Yet */ /* FUTURE: when it does, their may be no write arg! */ } if ((i+count) >= end ) { CLIWandException(OptionFatalError,"MissingArgument",option); if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse ) return(end); break; /* next option - not that their is any! */ } arg1 = ( count >= 1 ) ? argv[i+1] : (char *) NULL; arg2 = ( count >= 2 ) ? argv[i+2] : (char *) NULL; /* Process Known Options */ #if MagickCommandDebug >= 3 (void) FormatLocaleFile(stderr, "CLI arg %u Option: \"%s\" Count: %d Flags: %04x Args: \"%s\" \"%s\"\n", i,option,count,option_type,arg1,arg2); #endif /* ignore 'genesis options' in command line args */ if ( (option_type & GenesisOptionFlag) != 0 ) break; /* next option */ /* Handle any special options for CLI (-script handled above) */ if ( (option_type & SpecialOptionFlag) != 0 ) { if ( (cli_wand->process_flags & ProcessExitOption) != 0 && LocaleCompare(option,"-exit") == 0 ) return(i+count); break; /* next option */ } /* Process standard image option */ CLIOption(cli_wand, option, arg1, arg2); DisableMSCWarning(4127) } while (0); /* break block to next option */ RestoreMSCWarning #if MagickCommandDebug >= 5 (void) FormatLocaleFile(stderr, "CLI-post Image Count = %ld\n", (long) GetImageListLength(cli_wand->wand.images) ); #endif if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse ) return(i+count); } assert(i==end); if ( (cli_wand->process_flags & ProcessImplictWrite) == 0 ) return(end); /* no implied write -- just return to caller */ assert(end==argc-1); /* end should not include last argument */ /* Implicit Write of images to final CLI argument */ option=argv[i]; cli_wand->line=i; /* check that stacks are empty - or cause exception */ if (cli_wand->image_list_stack != (Stack *) NULL) CLIWandException(OptionError,"UnbalancedParenthesis", "(end of cli)"); else if (cli_wand->image_info_stack != (Stack *) NULL) CLIWandException(OptionError,"UnbalancedBraces", "(end of cli)"); if ( CLICatchException(cli_wand, MagickFalse) != MagickFalse ) return(argc); #if MagickCommandDebug >= 3 (void) FormatLocaleFile(stderr,"CLI arg %d Write File: \"%s\"\n",i,option); #endif /* Valid 'do no write' replacement option (instead of "null:") */ if (LocaleCompare(option,"-exit") == 0 ) return(argc); /* just exit, no image write */ /* If filename looks like an option, Or the common 'end of line' error of a single space. -- produce an error */ if (IfMagickTrue(IsCommandOption(option)) || (option[0] == ' ' && option[1] == '\0') ) { CLIWandException(OptionError,"MissingOutputFilename",option); return(argc); } cli_wand->command=(const OptionInfo *) NULL; CLIOption(cli_wand,"-write",option); return(argc); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + P r o c e s s S c r i p t O p t i o n s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ProcessScriptOptions() reads options and processes options as they are % found in the given file, or pipeline. The filename to open and read % options is given as the 'index' argument of the argument array given. % % Other arguments following index may be read by special script options % as settings (strings), images, or as operations to be processed in various % ways. How they are treated is up to the script being processed. % % Note that a script not 'return' to the command line processing, nor can % they call (and return from) other scripts. At least not at this time. % % There are no 'ProcessOptionFlags' control flags at this time. % % The format of the ProcessScriptOptions method is: % % void ProcessScriptOptions(MagickCLI *cli_wand,const char *filename, % int argc,char **argv,int index) % % A description of each parameter follows: % % o cli_wand: the main CLI Wand to use. % % o filename: the filename of script to process % % o argc: the number of elements in the argument vector. (optional) % % o argv: A text array containing the command line arguments. (optional) % % o index: offset of next argment in argv (script arguments) (optional) % */ WandExport void ProcessScriptOptions(MagickCLI *cli_wand,const char *filename, int argc,char **argv,int index) { ScriptTokenInfo *token_info; CommandOptionFlags option_type; int count; char *option, *arg1, *arg2; assert(filename != (char *) NULL ); /* at least one argument - script name */ assert(cli_wand != (MagickCLI *) NULL); assert(cli_wand->signature == WandSignature); if (IfMagickTrue(cli_wand->wand.debug)) (void) LogMagickEvent(CommandEvent,GetMagickModule(), "Processing script \"%s\"", filename); /* open file script or stream, and set up tokenizer */ token_info = AcquireScriptTokenInfo(filename); if (token_info == (ScriptTokenInfo *) NULL) { CLIWandExceptionFile(OptionFatalError,"UnableToOpenScript",filename); return; } /* define the error location string for use in exceptions order of localtion format escapes: filename, line, column */ cli_wand->location="in \"%s\" at line %u,column %u"; if ( LocaleCompare("-", filename) == 0 ) cli_wand->filename="stdin"; else cli_wand->filename=filename; /* Process Options from Script */ option = arg1 = arg2 = (char*) NULL; DisableMSCWarning(4127) while (1) { RestoreMSCWarning { MagickBooleanType status = GetScriptToken(token_info); cli_wand->line=token_info->token_line; cli_wand->column=token_info->token_column; if (status == MagickFalse) break; /* error or end of options */ } do { /* use break to loop to exception handler and loop */ /* save option details */ CloneString(&option,token_info->token); /* get option, its argument count, and option type */ cli_wand->command = GetCommandOptionInfo(option); count=cli_wand->command->type; option_type=(CommandOptionFlags) cli_wand->command->flags; #if 0 (void) FormatLocaleFile(stderr, "Script: %u,%u: \"%s\" matched \"%s\"\n", cli_wand->line, cli_wand->line, option, cli_wand->command->mnemonic ); #endif /* handle a undefined option - image read - always for "magick-script" */ if ( option_type == UndefinedOptionFlag || (option_type & NonMagickOptionFlag) != 0 ) { #if MagickCommandDebug >= 3 (void) FormatLocaleFile(stderr, "Script %u,%u Non-Option: \"%s\"\n", cli_wand->line, cli_wand->line, option); #endif if ( IfMagickFalse(IsCommandOption(option))) { /* non-option -- treat as a image read */ cli_wand->command=(const OptionInfo *) NULL; CLIOption(cli_wand,"-read",option); break; /* next option */ } CLIWandException(OptionFatalError,"UnrecognizedOption",option); break; /* next option */ } if ( count >= 1 ) { if( IfMagickFalse(GetScriptToken(token_info)) ) CLIWandException(OptionFatalError,"MissingArgument",option); CloneString(&arg1,token_info->token); } else CloneString(&arg1,(char *) NULL); if ( count >= 2 ) { if( IfMagickFalse(GetScriptToken(token_info)) ) CLIWandExceptionBreak(OptionFatalError,"MissingArgument",option); CloneString(&arg2,token_info->token); } else CloneString(&arg2,(char *) NULL); /* Process Options */ #if MagickCommandDebug >= 3 (void) FormatLocaleFile(stderr, "Script %u,%u Option: \"%s\" Count: %d Flags: %04x Args: \"%s\" \"%s\"\n", cli_wand->line,cli_wand->line,option,count,option_type,arg1,arg2); #endif /* Hard Deprecated Options, no code to execute - error */ if ( (option_type & DeprecateOptionFlag) != 0 ) { CLIWandException(OptionError,"DeprecatedOptionNoCode",option); break; /* next option */ } /* MagickCommandGenesis() options have no place in a magick script */ if ( (option_type & GenesisOptionFlag) != 0 ) { CLIWandException(OptionError,"InvalidUseOfOption",option); break; /* next option */ } /* handle any special 'script' options */ if ( (option_type & SpecialOptionFlag) != 0 ) { if ( LocaleCompare(option,"-exit") == 0 ) { goto loop_exit; /* break out of loop - return from script */ } if ( LocaleCompare(option,"-script") == 0 ) { /* FUTURE: call new script from this script - error for now */ CLIWandException(OptionError,"InvalidUseOfOption",option); break; /* next option */ } /* FUTURE: handle special script-argument options here */ /* handle any other special operators now */ CLIWandException(OptionError,"InvalidUseOfOption",option); break; /* next option */ } /* Process non-specific Option */ CLIOption(cli_wand, option, arg1, arg2); (void) fflush(stdout); (void) fflush(stderr); DisableMSCWarning(4127) } while (0); /* break block to next option */ RestoreMSCWarning #if MagickCommandDebug >= 5 fprintf(stderr, "Script Image Count = %ld\n", GetImageListLength(cli_wand->wand.images) ); #endif if ( IfMagickTrue(CLICatchException(cli_wand, MagickFalse)) ) break; /* exit loop */ } /* Loop exit - check for some tokenization error */ loop_exit: #if MagickCommandDebug >= 3 (void) FormatLocaleFile(stderr, "Script End: %d\n", token_info->status); #endif switch( token_info->status ) { case TokenStatusOK: case TokenStatusEOF: if (cli_wand->image_list_stack != (Stack *) NULL) CLIWandException(OptionError,"UnbalancedParenthesis", "(eof)"); else if (cli_wand->image_info_stack != (Stack *) NULL) CLIWandException(OptionError,"UnbalancedBraces", "(eof)"); break; case TokenStatusBadQuotes: /* Ensure last token has a sane length for error report */ if( strlen(token_info->token) > INITAL_TOKEN_LENGTH-1 ) { token_info->token[INITAL_TOKEN_LENGTH-4] = '.'; token_info->token[INITAL_TOKEN_LENGTH-3] = '.'; token_info->token[INITAL_TOKEN_LENGTH-2] = '.'; token_info->token[INITAL_TOKEN_LENGTH-1] = '\0'; } CLIWandException(OptionFatalError,"ScriptUnbalancedQuotes", token_info->token); break; case TokenStatusMemoryFailed: CLIWandException(OptionFatalError,"ScriptTokenMemoryFailed",""); break; case TokenStatusBinary: CLIWandException(OptionFatalError,"ScriptIsBinary",""); break; } (void) fflush(stdout); (void) fflush(stderr); if (IfMagickTrue(cli_wand->wand.debug)) (void) LogMagickEvent(CommandEvent,GetMagickModule(), "Script End \"%s\"", filename); /* Clean up */ token_info = DestroyScriptTokenInfo(token_info); CloneString(&option,(char *) NULL); CloneString(&arg1,(char *) NULL); CloneString(&arg2,(char *) NULL); return; }