/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d Y U V I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ReadYUVImage reads an image with digital YUV (CCIR 601 4:1:1) bytes % and returns it. It allocates the memory necessary for the new Image % structure and returns a pointer to the new image. % % The format of the ReadYUVImage method is: % % Image *ReadYUVImage(const ImageInfo *image_info) % % A description of each parameter follows: % % o image: Method ReadYUVImage 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 an ImageInfo structure. % % */ Export Image *ReadYUVImage(const ImageInfo *image_info) { Image *chroma_image, *image, *zoom_image; int count, y; register int i, x; register PixelPacket *q, *r; register unsigned char *p; unsigned char *scanline; unsigned int status; /* Allocate image structure. */ image=AllocateImage(image_info); if (image == (Image *) NULL) return((Image *) NULL); if ((image->columns == 0) || (image->rows == 0)) ReaderExit(OptionWarning,"Must specify image size",image); image->depth=8; if (image_info->interlace != PartitionInterlace) { /* Open image file. */ status=OpenBlob(image_info,image,ReadBinaryType); if (status == False) ReaderExit(FileOpenWarning,"Unable to open file",image); for (i=0; i < image->offset; i++) (void) ReadByte(image); } /* Allocate memory for a scanline. */ scanline=(unsigned char *) AllocateMemory(image->columns*sizeof(unsigned char)); if (scanline == (unsigned char *) NULL) ReaderExit(ResourceLimitWarning,"Memory allocation failed",image); do { /* Convert raster image to pixel packets. */ if (image_info->interlace == PartitionInterlace) { AppendImageFormat("Y",image->filename); status=OpenBlob(image_info,image,ReadBinaryType); if (status == False) ReaderExit(FileOpenWarning,"Unable to open file",image); } for (y=0; y < (int) image->rows; y++) { if ((y > 0) || (image->previous == (Image *) NULL)) (void) ReadBlob(image,image->columns,scanline); p=scanline; q=SetPixelCache(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) image->columns; x++) { q->red=UpScale(*p++); q->green=0; q->blue=0; q++; } if (!SyncPixelCache(image)) break; if (image->previous == (Image *) NULL) ProgressMonitor(LoadImageText,y,image->rows); } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("U",image->filename); status=OpenBlob(image_info,image,ReadBinaryType); if (status == False) ReaderExit(FileOpenWarning,"Unable to open file",image); } chroma_image=CloneImage(image,image->columns/2,image->rows/2,True); if (chroma_image == (Image *) NULL) ReaderExit(ResourceLimitWarning,"Memory allocation failed",image); for (y=0; y < (int) chroma_image->rows; y++) { (void) ReadBlob(image,chroma_image->columns,scanline); p=scanline; q=SetPixelCache(chroma_image,0,y,chroma_image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) chroma_image->columns; x++) { q->red=0; q->green=UpScale(*p++); q->blue=0; q++; } if (!SyncPixelCache(chroma_image)) break; } if (image_info->interlace == PartitionInterlace) { CloseBlob(image); AppendImageFormat("V",image->filename); status=OpenBlob(image_info,image,ReadBinaryType); if (status == False) ReaderExit(FileOpenWarning,"Unable to open file",image); } for (y=0; y < (int) chroma_image->rows; y++) { (void) ReadBlob(image,chroma_image->columns,scanline); p=scanline; q=GetPixelCache(chroma_image,0,y,chroma_image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) chroma_image->columns; x++) { q->blue=UpScale(*p++); q++; } if (!SyncPixelCache(chroma_image)) break; } /* Scale image. */ chroma_image->orphan=True; zoom_image=SampleImage(chroma_image,image->columns,image->rows); DestroyImage(chroma_image); if (zoom_image == (Image *) NULL) ReaderExit(ResourceLimitWarning,"Memory allocation failed",image); for (y=0; y < (int) image->rows; y++) { q=GetPixelCache(image,0,y,image->columns,1); r=GetPixelCache(zoom_image,0,y,zoom_image->columns,1); if ((q == (PixelPacket *) NULL) || (r == (PixelPacket *) NULL)) break; for (x=0; x < (int) image->columns; x++) { q->green=r->green; q->blue=r->blue; r++; q++; } if (!SyncPixelCache(image)) break; } DestroyImage(zoom_image); TransformRGBImage(image,YCbCrColorspace); if (image_info->interlace == PartitionInterlace) (void) strcpy(image->filename,image_info->filename); /* Proceed to next image. */ if (image_info->subrange != 0) if (image->scene >= (image_info->subimage+image_info->subrange-1)) break; count=ReadBlob(image,image->columns,(char *) scanline); if (count > 0) { /* Allocate next image structure. */ AllocateNextImage(image_info,image); if (image->next == (Image *) NULL) { DestroyImages(image); return((Image *) NULL); } image=image->next; ProgressMonitor(LoadImagesText,TellBlob(image),image->filesize); } } while (count > 0); FreeMemory(scanline); while (image->previous != (Image *) NULL) image=image->previous; CloseBlob(image); return(image); }
Export Image *ReadSFWImage(const ImageInfo *image_info) { static unsigned char HuffmanTable[] = { 0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA }; FILE *file; Image *flipped_image, *image; ImageInfo *local_info; register unsigned char *header, *data; unsigned char *buffer, *offset; unsigned int status; /* Allocate image structure. */ image=AllocateImage(image_info); if (image == (Image *) NULL) return((Image *) NULL); /* Open image file. */ status=OpenBlob(image_info,image,ReadBinaryType); if (status == False) ReaderExit(FileOpenWarning,"Unable to open file",image); /* Read image into a buffer. */ buffer=(unsigned char *) AllocateMemory(image->filesize*sizeof(unsigned char)); if (buffer == (unsigned char *) NULL) ReaderExit(ResourceLimitWarning,"Memory allocation failed",image); status=ReadBlob(image,image->filesize,(char *) buffer); if ((status == False) || (strncmp((char *) buffer,"SFW",3) != 0)) ReaderExit(CorruptImageWarning,"Not a SFW image file",image); CloseBlob(image); DestroyImage(image); /* Find the start of the JFIF data */ header=SFWScan(buffer,buffer+image->filesize-1,(unsigned char *) "\377\310\377\320",4); if (header == (unsigned char *) NULL) { FreeMemory(buffer); ReaderExit(CorruptImageWarning,"Not a SFW image file",image); } TranslateSFWMarker(header); /* translate soi and app tags */ TranslateSFWMarker(header+2); (void) memcpy((char *) header+6,"JFIF\0\001\0",7); /* JFIF magic */ /* Translate remaining markers. */ offset=header+2; offset+=(offset[2] << 8)+offset[3]+2; for ( ; ; ) { TranslateSFWMarker(offset); if (offset[1] == 0xda) break; offset+=(offset[2] << 8)+offset[3]+2; } offset--; data=SFWScan(offset,buffer+image->filesize-1,(unsigned char *) "\377\311",2); if (data == (unsigned char *) NULL) { FreeMemory(buffer); ReaderExit(CorruptImageWarning,"Not a SFW image file",image); } TranslateSFWMarker(data++); /* translate eoi marker */ /* Write JFIF file. */ local_info=CloneImageInfo(image_info); TemporaryFilename(local_info->filename); file=fopen(local_info->filename,WriteBinaryType); if (file == (FILE *) NULL) { FreeMemory(buffer); DestroyImageInfo(local_info); ReaderExit(FileOpenWarning,"Unable to write file",image); } (void) fwrite(header,offset-header+1,1,file); (void) fwrite(HuffmanTable,1,sizeof(HuffmanTable)/sizeof(*HuffmanTable),file); (void) fwrite(offset+1,data-offset,1,file); status=ferror(file); (void) fclose(file); FreeMemory(buffer); if (status) { (void) remove(local_info->filename); DestroyImageInfo(local_info); ReaderExit(FileOpenWarning,"Unable to write file",image); } /* Read JPEG image. */ image=ReadImage(local_info); (void) remove(local_info->filename); DestroyImageInfo(local_info); if (image == (Image *) NULL) return(image); /* Correct image orientation. */ flipped_image=FlipImage(image); if (flipped_image == (Image *) NULL) return(image); DestroyImage(image); return(flipped_image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d S C T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ReadSCTImage reads a Scitex image file and returns it. It allocates % the memory necessary for the new Image structure and returns a pointer to % the new image. % % The format of the ReadSCTImage method is: % % Image *ReadSCTImage(const ImageInfo *image_info) % % A description of each parameter follows: % % o image: Method ReadSCTImage 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 an ImageInfo structure. % % */ Export Image *ReadSCTImage(const ImageInfo *image_info) { char buffer[768], magick[2]; Image *image; int y; register int x; register PixelPacket *q; unsigned int status; /* Allocate image structure. */ image=AllocateImage(image_info); if (image == (Image *) NULL) return((Image *) NULL); /* Open image file. */ status=OpenBlob(image_info,image,ReadBinaryType); if (status == False) ReaderExit(FileOpenWarning,"Unable to open file",image); /* Read control block. */ (void) ReadBlob(image,80,(char *) buffer); (void) ReadBlob(image,2,(char *) magick); if ((strncmp((char *) magick,"CT",2) != 0) && (strncmp((char *) magick,"LW",2) != 0) && (strncmp((char *) magick,"BM",2) != 0) && (strncmp((char *) magick,"PG",2) != 0) && (strncmp((char *) magick,"TX",2) != 0)) ReaderExit(CorruptImageWarning,"Not a SCT image file",image); if ((strncmp((char *) magick,"LW",2) == 0) || (strncmp((char *) magick,"BM",2) == 0) || (strncmp((char *) magick,"PG",2) == 0) || (strncmp((char *) magick,"TX",2) == 0)) ReaderExit(CorruptImageWarning,"only Continuous Tone Picture supported", image); (void) ReadBlob(image,174,(char *) buffer); (void) ReadBlob(image,768,(char *) buffer); /* Read paramter block. */ (void) ReadBlob(image,32,(char *) buffer); (void) ReadBlob(image,14,(char *) buffer); image->rows=atoi(buffer); (void) ReadBlob(image,14,(char *) buffer); image->columns=atoi(buffer); (void) ReadBlob(image,196,(char *) buffer); (void) ReadBlob(image,768,(char *) buffer); if (image_info->ping) { CloseBlob(image); return(image); } /* Convert SCT raster image to pixel packets. */ image->colorspace=CMYKColorspace; for (y=0; y < (int) image->rows; y++) { q=SetPixelCache(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) image->columns; x++) { q->red=MaxRGB-UpScale(ReadByte(image)); q++; } if ((image->columns % 2) != 0) (void) ReadByte(image); /* pad */ q=GetPixelCache(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) image->columns; x++) { q->green=MaxRGB-UpScale(ReadByte(image)); q++; } if ((image->columns % 2) != 0) (void) ReadByte(image); /* pad */ q=GetPixelCache(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) image->columns; x++) { q->blue=MaxRGB-UpScale(ReadByte(image)); q++; } if ((image->columns % 2) != 0) (void) ReadByte(image); /* pad */ q=GetPixelCache(image,0,y,image->columns,1); if (q == (PixelPacket *) NULL) break; for (x=0; x < (int) image->columns; x++) { q->opacity=MaxRGB-UpScale(ReadByte(image)); q++; } if (!SyncPixelCache(image)) break; if ((image->columns % 2) != 0) (void) ReadByte(image); /* pad */ if (QuantumTick(y,image->rows)) ProgressMonitor(LoadImageText,y,image->rows); } return(image); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d I P T C I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ReadIPTCImage reads an image file in the IPTC format and returns it. % It allocates the memory necessary for the new Image structure and returns a % pointer to the new image. This method differs from the other decoder % methods in that only the iptc profile information is useful in the % returned image. % % The format of the ReadIPTCImage method is: % % Image *ReadIPTCImage(const ImageInfo *image_info) % % A description of each parameter follows: % % o image: Method ReadIPTCImage 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 an ImageInfo structure. % % */ Export Image *ReadIPTCImage(const ImageInfo *image_info) { Image *image; int c; register unsigned char *q; unsigned char *data; unsigned int tag_length, length, status; /* Allocate image structure. */ image=AllocateImage(image_info); if (image == (Image *) NULL) return((Image *) NULL); /* Open image file. */ status=OpenBlob(image_info,image,ReadBinaryType); if (status == False) ReaderExit(FileOpenWarning,"Unable to open file",image); /* Read IPTC image. */ length=MaxTextExtent; tag_length=12; data=(unsigned char *) AllocateMemory((length+2)*sizeof(unsigned char)); if (data == (unsigned char *) NULL) WriterExit(ResourceLimitWarning,"Memory allocation failed",image); (void) memcpy((char *) data,"8BIM\04\04\0\0\0\0\0\0",tag_length); q=data; q+=tag_length; while (1) { c=ReadByte(image); if (c == EOF) break; if ((q-data+1) >= (int) length) { image->iptc_profile.length=q-data; length<<=1; data=(unsigned char *) ReallocateMemory((char *) data,(length+2)*sizeof(unsigned char)); if (data == (unsigned char *) NULL) break; q=data+image->iptc_profile.length; } *q++=(unsigned char) c; } image->iptc_profile.length=0; if (data != (unsigned char *) NULL) { image->iptc_profile.length=q-data; length=image->iptc_profile.length-tag_length; data[10]=length >> 8; data[11]=length & 0xff; image->iptc_profile.info=data; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d T T F I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method ReadTTFImage reads a TrueType font file and returns it. It % allocates the memory necessary for the new Image structure and returns a % pointer to the new image. % % The format of the ReadTTFImage method is: % % Image *ReadTTFImage(const ImageInfo *image_info) % % A description of each parameter follows: % % o image: Method ReadTTFImage 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 an ImageInfo structure. % % */ Export Image *ReadTTFImage(const ImageInfo *image_info) { AnnotateInfo *annotate_info; char font[MaxTextExtent], geometry[MaxTextExtent], text[MaxTextExtent]; Image *image; int y; long magick; register int i; ImageInfo *local_info; unsigned int status; /* Allocate image structure. */ image=AllocateImage(image_info); if (image == (Image *) NULL) return((Image *) NULL); /* Open image file. */ status=OpenBlob(image_info,image,ReadBinaryType); if (status == False) ReaderExit(FileOpenWarning,"Unable to open file",image); magick=MSBFirstReadLong(image); if ((magick != 256) && (magick != 65536)) ReaderExit(CorruptImageWarning,"Not a TTF font file",image); /* Start with a white canvas. */ y=0; local_info=CloneImageInfo(image_info); if (local_info == (ImageInfo *) NULL) return((Image *) NULL); (void) CloneString(&local_info->size,"800x520"); (void) CloneString(&local_info->pen,"black"); *font='\0'; (void) CloneString(&local_info->font,font); local_info->pointsize=18; FormatString(local_info->font,"@%.1024s",image_info->filename); annotate_info=CloneAnnotateInfo(local_info,(AnnotateInfo *) NULL); image->columns=annotate_info->bounds.width; image->rows=annotate_info->bounds.height; if (image_info->ping) { DestroyAnnotateInfo(annotate_info); DestroyImageInfo(local_info); CloseBlob(image); return(image); } DestroyImage(image); (void) strcpy(local_info->filename,"white"); image=ReadXCImage(local_info); DestroyImageInfo(local_info); if (image == (Image *) NULL) { DestroyAnnotateInfo(annotate_info); return((Image *) NULL); } (void) strcpy(image->filename,image_info->filename); if (annotate_info->font_name != (char *) NULL) (void) CloneString(&image->label,annotate_info->font_name); /* Annotate canvas with text rendered with font at different point sizes. */ y=10; if (annotate_info->font_name != (char *) NULL) { annotate_info->image_info->pointsize=30; FormatString(geometry,"+10%+d",y); (void) CloneString(&annotate_info->geometry,geometry); (void) CloneString(&annotate_info->text,annotate_info->font_name); AnnotateImage(image,annotate_info); y+=42; } annotate_info->image_info->pointsize=18; FormatString(geometry,"+10%+d",y); (void) CloneString(&annotate_info->geometry,geometry); (void) CloneString(&annotate_info->text,"abcdefghijklmnopqrstuvwxyz"); AnnotateImage(image,annotate_info); y+=20; FormatString(geometry,"+10%+d",y); (void) CloneString(&annotate_info->geometry,geometry); (void) CloneString(&annotate_info->text,"ABCDEFGHIJKLMNOPQRSTUVWXYZ"); AnnotateImage(image,annotate_info); y+=20; FormatString(geometry,"+10%+d",y); (void) CloneString(&annotate_info->geometry,geometry); (void) CloneString(&annotate_info->text,"1234567890.:,;(:*!?')"); AnnotateImage(image,annotate_info); y+=20; for (i=12; i <= 72; i+=6) { y+=i+6; annotate_info->image_info->pointsize=18; FormatString(geometry,"+10%+d",y); (void) CloneString(&annotate_info->geometry,geometry); FormatString(text,"%d",i); (void) CloneString(&annotate_info->text,text); AnnotateImage(image,annotate_info); annotate_info->image_info->pointsize=i; FormatString(geometry,"+50%+d",y); (void) CloneString(&annotate_info->geometry,geometry); (void) CloneString(&annotate_info->text, "That which does not destroy me, only makes me stronger"); AnnotateImage(image,annotate_info); if (i >= 24) i+=6; } DestroyAnnotateInfo(annotate_info); return(image); }