/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d T X T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ReadTXTImage reads a text file and returns it as an image. It % allocates the memory necessary for the new Image structure and returns a % pointer to the new image. % % The format of the ReadTXTImage method is: % % Image *ReadTXTImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: Method ReadTXTImage returns a pointer to the image after % reading. A null image is returned if there is a memory shortage or if % the image cannot be read. % % o image_info: Specifies a pointer to a ImageInfo structure. % % o exception: return any errors or warnings in this structure. % % */ static Image *ReadTXTImage(const ImageInfo *image_info,ExceptionInfo *exception) { char *p, text[MaxTextExtent]; Image *image; TXT_TYPE txt_subformat; MagickPassFail status; MagickBool logging; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); logging = IsEventLogging(); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == False) ThrowReaderException(FileOpenError,UnableToOpenFile,image); p = ReadBlobString(image,text); if (p == NULL) ThrowReaderException(CorruptImageError,ImproperImageHeader,image); txt_subformat = IsTXT((unsigned char *)p,strlen(p)); if (txt_subformat != NO_TXT) { unsigned x, y; unsigned x_min, x_max, y_curr; int ch; unsigned long max, i; char NumOfPlanes; unsigned char *BImgBuff; magick_uint16_t *WImgBuff; magick_uint32_t *DImgBuff; magick_uint32_t R, G, B, A; const PixelPacket *q; ExtendedSignedIntegralType NextImagePos = 0; ImportPixelAreaOptions import_options; if (logging) (void) LogMagickEvent(CoderEvent,GetMagickModule(), "File RAW TXT type: %d", (int) txt_subformat); do { (void) SeekBlob(image,NextImagePos,SEEK_SET); if(NextImagePos!=0) { /* Allocate next image structure. */ AllocateNextImage(image_info,image); if(image->next == (Image *)NULL) break; image = SyncNextImageInList(image); image->columns = image->rows = 0; image->colors=0; } A=0; x=0; y=0; max=0; switch(txt_subformat) { case TXT_GM8B_HEX: case TXT_GM8B_HEX_Q: max=255; break; case TXT_GM16B_HEX: case TXT_GM16B_HEX_Q: max=65535; break; case TXT_GM32B_HEX: case TXT_GM32B_HEX_Q: max=65536; break; default: break; } /* Set opacity flag. */ image->matte=MagickFalse; if (txt_subformat >= IMAGEMAGICK_TXT_Q) image->matte=MagickTrue; if (!strncmp(p,"# ImageMagick pixel enumeration:",32)) { if (sscanf(p+32,"%u,%u,%u",&x_min,&y_curr,&x_max) == 3) { if (strstr(p+32,",rgb")!=NULL) { x = x_min-1; y = y_curr-1; max = x_max; } if (strstr(p+32,",rgba")!=NULL) { txt_subformat = IMAGEMAGICK_TXT_Q; } } } ch=0; if (x == 0 && y == 0) while (!EOFBlob(image)) /* auto detect sizes and num of planes */ { while (!(ch >= '0' && ch <= '9')) { /* go to the begin of number */ ch = ReadBlobByte(image); if (ch == EOF) goto EndReading; if (ch == '#') { readln(image,&ch); continue; } if (ch == 0 || ch > 128 || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { TXT_FAIL: /* not a text data */ ThrowReaderException(CoderError,ImageTypeNotSupported,image); } } /* x,y: (R,G,B) */ x_min = ReadInt(image,&ch); /* x */ if (x_min > x) x = x_min; while (ch != ',') { ch = ReadBlobByte(image); if (ch==EOF) break; if (ch == 10 || ch == 13) goto TXT_FAIL; } ch=0; i=ReadInt(image,&ch); /* y */ /* Check for next image start. */ if(x_min==0 && i==0 && x>0 && y>0) goto EndReading; if (i > y) y=i; while (ch != ':') { ch = ReadBlobByte(image); if (ch == 10 || ch == 13) goto TXT_FAIL; if (ch == EOF) break; } if (txt_subformat != TXT_GM8B_PLAIN2_Q) while (ch != '(') { ch = ReadBlobByte(image); if (ch == 10 || ch == 13) goto TXT_FAIL; if (ch == EOF) break; } ch=0; R = ReadInt(image,&ch); /* R */ if (R > max) max=R; while (ch != ',') { ch = ReadBlobByte(image); if (ch == 10 || ch == 13) goto TXT_FAIL; if (ch == EOF) break; } ch=0; G = ReadInt(image,&ch); /* G */ if (G > max) max=G; while (ch != ',') { ch = ReadBlobByte(image); if (ch == 10 || ch == 13) goto TXT_FAIL; if (ch == EOF) break; } ch=0; B = ReadInt(image,&ch); /* B */ if (B > max) max=B; if (txt_subformat >= IMAGEMAGICK_TXT_Q) { while (ch != ',') { ch = ReadBlobByte(image); if (ch == 10 || ch == 13) goto TXT_FAIL; if (ch == EOF) break; } ch=0; A = ReadInt(image,&ch); /* A */ if (A > max) max=A; } if (txt_subformat != TXT_GM8B_PLAIN2_Q) while (ch != ')') { ch = ReadBlobByte(image); if (ch == 10 || ch == 13) goto TXT_FAIL; if (ch == EOF) break; } readln(image,&ch); } EndReading: x_min = 1; x_max = 0; y_curr = 0; NumOfPlanes=8; /* if (max>= 2) NumOfPlanes=2; */ /* if (max>= 4) NumOfPlanes=4; */ /* if (max>= 16) NumOfPlanes=8; */ if (max >= 256) NumOfPlanes=16; if (max >=65536) NumOfPlanes=32; if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(), "Image detected [%u * %u]: %d", x, y, NumOfPlanes); image->depth = Min(QuantumDepth,NumOfPlanes); ImportPixelAreaOptionsInit(&import_options); import_options.endian = NativeEndian; BImgBuff = MagickAllocateArray(unsigned char *, (size_t)(x+1), ( ((image->matte) ? 4 : 3) * NumOfPlanes/8)); WImgBuff = (magick_uint16_t *)BImgBuff; DImgBuff = (magick_uint32_t *)BImgBuff; if (BImgBuff == NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); image->columns = x+1; image->rows = y+1; (void) SeekBlob(image,NextImagePos,SEEK_SET); NextImagePos = 0; /* Load picture data */ while (!EOFBlob(image)) { x=0; while (!(ch >= '0' && ch <= '9')) { /* move to the beginning of number */ if (EOFBlob(image)) goto FINISH; ch = ReadBlobByte(image); if (ch == '#') { readln(image,&ch); continue; } } x = ReadInt(image,&ch); /* x */ while (ch != ',') { ch = ReadBlobByte(image); if (ch == EOF) break; } ch = 0; y = ReadInt(image,&ch); /* y */ /* New image detected. */ if(x==0 && y==0 && y_curr>0 && x_max>0) { NextImagePos = TellBlob(image) - 4; break; } while (ch != ':') { ch = ReadBlobByte(image); if (ch == EOF) break; } while (ch != '(') { ch = ReadBlobByte(image); if (ch == EOF) break; } ch=0; R = ReadInt(image,&ch); /* R */ while (ch != ',') { ch = ReadBlobByte(image); if (ch == EOF) break; } ch=0; G = ReadInt(image,&ch); /* G */ while (ch != ',') { ch = ReadBlobByte(image); if (ch == EOF) break; } ch=0; B = ReadInt(image,&ch); /* B */ if (image->matte) { while (ch != ',') { ch = ReadBlobByte(image); if (ch == EOF) break; } ch=0; A = ReadInt(image,&ch); /* A */ if (A > max) max=A; } while (ch != ')') { ch = ReadBlobByte(image); if (ch == EOF) break; } /* A new line has been detected */ if (y != y_curr) { q = SetImagePixels(image,x_min,y_curr,x_max-x_min+1,1); if (q == (PixelPacket *)NULL) break; if (image->matte) (void)ImportImagePixelArea(image,RGBAQuantum,NumOfPlanes, BImgBuff + 4*x_min*(NumOfPlanes/8), &import_options,0); else (void)ImportImagePixelArea(image,RGBQuantum,NumOfPlanes, BImgBuff + 3*x_min*(NumOfPlanes/8), &import_options,0); if (!SyncImagePixels(image)) break; x_min = 1; x_max = 0; y_curr=y; } if (x < image->columns) { if (image->matte) { switch(NumOfPlanes) { case 8: BImgBuff[0+4*x] = R; BImgBuff[1+4*x] = G; BImgBuff[2+4*x] = B; BImgBuff[3+4*x] = 255U-A; break; case 16: WImgBuff[0+4*x] = R; WImgBuff[1+4*x] = G; WImgBuff[2+4*x] = B; WImgBuff[3+4*x] = 65535U-A; break; case 32: DImgBuff[0+4*x] = R; DImgBuff[1+4*x] = G; DImgBuff[2+4*x] = B; DImgBuff[3+4*x] = 4294967295U-A; break; } } else { switch(NumOfPlanes) { case 8: BImgBuff[0+3*x] = R; BImgBuff[1+3*x] = G; BImgBuff[2+3*x] = B; break; case 16: WImgBuff[0+3*x] = R; WImgBuff[1+3*x] = G; WImgBuff[2+3*x] = B; break; case 32: DImgBuff[0+3*x] = R; DImgBuff[1+3*x] = G; DImgBuff[2+3*x] = B; break; } } if (x_min > x_max) { x_max=x_min=x; } else { if (x < x_min) x_min=x; if (x > x_max) x_max=x; } } readln(image,&ch); } FINISH: if (x_min <= x_max) { q = SetImagePixels(image,x_min,y_curr,x_max-x_min+1,1); if (q != (PixelPacket *)NULL) { if (image->matte) (void)ImportImagePixelArea(image, RGBAQuantum, NumOfPlanes, BImgBuff + 4*x_min*(NumOfPlanes/8), &import_options, 0); else (void)ImportImagePixelArea(image, RGBQuantum, NumOfPlanes, BImgBuff + 3*x_min*(NumOfPlanes/8), &import_options, 0); if (!SyncImagePixels(image)) { if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(), " TXT failed to sync image pixels for a row %u", y_curr); } } } MagickFreeMemory(BImgBuff); } while(!EOFBlob(image) && NextImagePos>0); goto FINISH_TXT; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d T X T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ReadTXTImage reads a text file and returns it as an image. It % allocates the memory necessary for the new Image structure and returns a % pointer to the new image. % % The format of the ReadTXTImage method is: % % Image *ReadTXTImage(const ImageInfo *image_info,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: Method ReadTXTImage returns a pointer to the image after % reading. A null image is returned if there is a memory shortage or if % the image cannot be read. % % o image_info: Specifies a pointer to a ImageInfo structure. % % o exception: return any errors or warnings in this structure. % % */ static Image *ReadTXTImage(const ImageInfo *image_info,ExceptionInfo *exception) { char filename[MaxTextExtent], geometry[MaxTextExtent], *p, text[MaxTextExtent]; double dx_resolution, dy_resolution; DrawInfo *draw_info; Image *image, *texture; long count, offset; RectangleInfo page; TypeMetric metrics; unsigned int status; int logging; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); logging = LogMagickEvent(CoderEvent,GetMagickModule(),"enter"); image=AllocateImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == False) ThrowReaderException(FileOpenError,UnableToOpenFile,image); p = ReadBlobString(image,text); status = IsTXT((unsigned char *)p,strlen(p)); if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(), "File type: %d", status); if(status) { unsigned x,y; unsigned x_min,x_max,y_curr; int ch; unsigned long max,i; char NumOfPlanes; unsigned char *BImgBuff; magick_uint16_t *WImgBuff; magick_uint32_t *DImgBuff; magick_uint32_t R,G,B,A; const PixelPacket *q; ImportPixelAreaOptions import_options; (void) SeekBlob(image,0,SEEK_SET); A=0; x=0; y=0; max=0; switch(status) { case TXT_GM8B_HEX: case TXT_GM8B_HEX_Q: max=255; break; case TXT_GM16B_HEX: case TXT_GM16B_HEX_Q: max=65535; break; case TXT_GM32B_HEX: case TXT_GM32B_HEX_Q: max=65536; break; } if(!strncmp(p,"# ImageMagick pixel enumeration:",32)) { if(sscanf(p+32,"%u,%u,%u",&x_min,&y_curr,&x_max)==3) { if(strstr(p+32,",rgb")!=NULL) { x = x_min-1; y = y_curr-1; max = x_max; } if(strstr(p+32,",rgba")!=NULL) { status = IMAGEMAGICK_TXT_Q; } } } ch=0; if(x==0 && y==0) while(!EOFBlob(image)) /* auto detect sizes and num of planes */ { while(!(ch>='0' && ch<='9')) { /* go to the begin of number */ ch = ReadBlobByte(image); if(ch==EOF) goto EndReading; if(ch=='#') {readln(image,&ch); continue;} if(ch==0 || ch>128 || (ch>='a' && ch<='z') || (ch>='A' && ch<='Z')) { TXT_FAIL: /* not a text data */ ThrowReaderException(CoderError,ImageTypeNotSupported,image); } } /* x,y: (R,G,B) */ i = ReadInt(image,&ch); /* x */ if(i>x) x=i; while(ch!=',') { ch = ReadBlobByte(image); if(ch==EOF) break; if(ch==10 || ch==13) goto TXT_FAIL; } ch=0; i=ReadInt(image,&ch); /* y */ if(i>y) y=i; while(ch!=':') { ch = ReadBlobByte(image); if(ch==10 || ch==13) goto TXT_FAIL; if(ch==EOF) break; } if(status!=TXT_GM8B_PLAIN2_Q) while(ch!='(') { ch = ReadBlobByte(image); if(ch==10 || ch==13) goto TXT_FAIL; if(ch==EOF) break; } ch=0; R = ReadInt(image,&ch); /* R */ if(R>max) max=R; while(ch!=',') { ch = ReadBlobByte(image); if(ch==10 || ch==13) goto TXT_FAIL; if(ch==EOF) break; } ch=0; G = ReadInt(image,&ch); /* G */ if(G>max) max=G; while(ch!=',') { ch = ReadBlobByte(image); if(ch==10 || ch==13) goto TXT_FAIL; if(ch==EOF) break; } ch=0; B = ReadInt(image,&ch); /* B */ if(B>max) max=B; if(status>16) { while(ch!=',') { ch = ReadBlobByte(image); if(ch==10 || ch==13) goto TXT_FAIL; if(ch==EOF) break; } ch=0; A = ReadInt(image,&ch); /* A */ if(A>max) max=A; } if(status!=TXT_GM8B_PLAIN2_Q) while(ch!=')') { ch = ReadBlobByte(image); if(ch==10 || ch==13) goto TXT_FAIL; if(ch==EOF) break; } readln(image,&ch); } EndReading: x_min = 1; x_max = 0; y_curr = 0; NumOfPlanes=8; /* if(max>= 2) i=2; */ /* if(max>= 4) i=4; */ /* if(max>= 16) i=8; */ if(max>= 256) NumOfPlanes=16; if(max>=65536) NumOfPlanes=32; if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(), "Image detected [%u * %u]: %d", x, y, NumOfPlanes); image->depth = Min(QuantumDepth,NumOfPlanes); ImportPixelAreaOptionsInit(&import_options); import_options.endian = NativeEndian; BImgBuff = MagickAllocateMemory(unsigned char *, (size_t)(x+1) * ( ((status>16)?4:3) * NumOfPlanes/8)); WImgBuff = (magick_uint16_t *)BImgBuff; DImgBuff = (magick_uint32_t *)BImgBuff; if(BImgBuff==NULL) ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); image->columns = x+1; image->rows = y+1; (void) SeekBlob(image,0,SEEK_SET); while(!EOFBlob(image)) /* load picture data */ { x=0; while(!(ch >= '0' && ch <= '9')) { /* move to the beginning of number */ if(EOFBlob(image)) goto FINISH; ch = ReadBlobByte(image); if(ch=='#') {readln(image,&ch); continue;} } x = ReadInt(image,&ch); /* x */ while(ch!=',') { ch = ReadBlobByte(image); if(ch==EOF) break; } ch = 0; y = ReadInt(image,&ch); /* y */ while(ch!=':') { ch = ReadBlobByte(image); if(ch==EOF) break; } while(ch!='(') { ch = ReadBlobByte(image); if(ch==EOF) break; } ch=0; R = ReadInt(image,&ch); /* R */ while(ch!=',') { ch = ReadBlobByte(image); if(ch==EOF) break; } ch=0; G = ReadInt(image,&ch); /* G */ while(ch!=',') { ch = ReadBlobByte(image); if(ch==EOF) break; } ch=0; B = ReadInt(image,&ch); /* B */ if(status>16) { while(ch!=',') { ch = ReadBlobByte(image); if(ch==EOF) break; } ch=0; A = ReadInt(image,&ch); /* A */ if(A>max) max=A; } while(ch!=')') { ch = ReadBlobByte(image); if(ch==EOF) break; } /* a new line has been detected */ if(y!=y_curr) { q = SetImagePixels(image,x_min,y_curr,x_max-x_min+1,1); if (q == (PixelPacket *)NULL) break; if(status>16) (void)ImportImagePixelArea(image,RGBAQuantum,NumOfPlanes, BImgBuff + 4*x_min*(NumOfPlanes/8),&import_options,0); else (void)ImportImagePixelArea(image,RGBQuantum,NumOfPlanes, BImgBuff + 3*x_min*(NumOfPlanes/8),&import_options,0); if (!SyncImagePixels(image)) break; x_min = 1; x_max = 0; y_curr=y; } if(x<image->columns) { if(status>16) { switch(NumOfPlanes) { case 8: BImgBuff[0+4*x] = R; BImgBuff[1+4*x] = G; BImgBuff[2+4*x] = B; BImgBuff[3+4*x] = A; break; case 16:WImgBuff[0+4*x] = R; WImgBuff[1+4*x] = G; WImgBuff[2+4*x] = B; WImgBuff[3+4*x] = A; break; case 32:DImgBuff[0+4*x] = R; DImgBuff[1+4*x] = G; DImgBuff[2+4*x] = B; DImgBuff[3+4*x] = A; break; } } else { switch(NumOfPlanes) { case 8: BImgBuff[0+3*x] = R; BImgBuff[1+3*x] = G; BImgBuff[2+3*x] = B; break; case 16:WImgBuff[0+3*x] = R; WImgBuff[1+3*x] = G; WImgBuff[2+3*x] = B; break; case 32:DImgBuff[0+3*x] = R; DImgBuff[1+3*x] = G; DImgBuff[2+3*x] = B; break; } } if(x_min>x_max) x_max=x_min=x; else { if(x<x_min) x_min=x; if(x>x_max) x_max=x; } } readln(image,&ch); } FINISH: if(x_min<=x_max) { q = SetImagePixels(image,x_min,y_curr,x_max-x_min+1,1); if (q != (PixelPacket *)NULL) { if(status>16) (void)ImportImagePixelArea(image, RGBAQuantum, NumOfPlanes, BImgBuff + 4*x_min*(NumOfPlanes/8), &import_options, 0); else (void)ImportImagePixelArea(image, RGBQuantum, NumOfPlanes, BImgBuff + 3*x_min*(NumOfPlanes/8), &import_options, 0); if(!SyncImagePixels(image)) { if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(), " TXT failed to sync image pixels for a row %u", y_curr); } } } MagickFreeMemory(BImgBuff); goto TXT_FINISH; } /* Set the page geometry. */ dx_resolution=72.0; dy_resolution=72.0; if ((image->x_resolution == 0.0) || (image->y_resolution == 0.0)) { char density[MaxTextExtent]; (void) strcpy(density,PSDensityGeometry); count=GetMagickDimension(density,&image->x_resolution, &image->y_resolution,NULL,NULL); if (count != 2) image->y_resolution=image->x_resolution; } SetGeometry(image,&page); page.width=612; page.height=792; (void) GetGeometry("612x792+43+43",&page.x,&page.y,&page.width,&page.height); if (image_info->page != (char *) NULL) (void) GetGeometry(image_info->page,&page.x,&page.y,&page.width, &page.height); /* Initialize Image structure. */ image->columns=(unsigned long) ceil(((page.width*image->x_resolution)/dx_resolution)-0.5); image->rows=(unsigned long) ceil(((page.height*image->y_resolution)/dy_resolution)-0.5); texture=(Image *) NULL; if (image_info->texture != (char *) NULL) { ImageInfo *clone_info; clone_info=CloneImageInfo(image_info); clone_info->blob=(void *) NULL; clone_info->length=0; (void) strlcpy(clone_info->filename,image_info->texture,MaxTextExtent); texture=ReadImage(clone_info,exception); DestroyImageInfo(clone_info); } /* Annotate the text image. */ (void) SetImage(image,OpaqueOpacity); draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL); draw_info->fill=image_info->pen; (void) CloneString(&draw_info->text,image_info->filename); FormatString(geometry,"0x0%+ld%+ld",page.x,page.y); (void) CloneString(&draw_info->geometry,geometry); status=GetTypeMetrics(image,draw_info,&metrics); if (status == False) ThrowReaderException(TypeError,UnableToGetTypeMetrics,image); (void) strlcpy(filename,image_info->filename,MaxTextExtent); if (draw_info->text != '\0') *draw_info->text='\0'; for (offset=2*page.y; p != (char *) NULL; ) { /* Annotate image with text. */ (void) ConcatenateString(&draw_info->text,text); (void) ConcatenateString(&draw_info->text,"\\n"); offset+=(long) (metrics.ascent-metrics.descent); if (image->previous == (Image *) NULL) if (QuantumTick(offset,image->rows)) if (!MagickMonitorFormatted(offset,image->rows,&image->exception, LoadImageText,image->filename, image->columns,image->rows)) break; p=ReadBlobString(image,text); if ((offset < (long) image->rows) && (p != (char *) NULL)) continue; if (texture != (Image *) NULL) { MonitorHandler handler; handler=SetMonitorHandler((MonitorHandler) NULL); (void) TextureImage(image,texture); (void) SetMonitorHandler(handler); } (void) AnnotateImage(image,draw_info); if (p == (char *) NULL) break; /* Page is full-- allocate next image structure. */ *draw_info->text='\0'; offset=2*page.y; AllocateNextImage(image_info,image); if (image->next == (Image *) NULL) { DestroyImageList(image); return((Image *) NULL); } image->next->columns=image->columns; image->next->rows=image->rows; image=SyncNextImageInList(image); (void) strlcpy(image->filename,filename,MaxTextExtent); (void) SetImage(image,OpaqueOpacity); if (!MagickMonitorFormatted(TellBlob(image),GetBlobSize(image),exception, LoadImagesText,image->filename)) break; } if (texture != (Image *) NULL) { MonitorHandler handler; handler=SetMonitorHandler((MonitorHandler) NULL); (void) TextureImage(image,texture); (void) SetMonitorHandler(handler); } (void) AnnotateImage(image,draw_info); if (texture != (Image *) NULL) DestroyImage(texture); DestroyDrawInfo(draw_info); while (image->previous != (Image *) NULL) image=image->previous; TXT_FINISH: CloseBlob(image); return(image); }