/* zoom.c: * * zoom an image * * jim frost 10.11.89 * * Copyright 1989 Jim Frost. See included file "copyright.h" for complete * copyright information. */ #include "copyright.h" #include "image.h" static unsigned int *buildIndex(width, zoom, rwidth) unsigned int width; float zoom; unsigned int *rwidth; { float fzoom; unsigned int *index; unsigned int a; if (!zoom) { fzoom= 100.0; *rwidth= width; } else { fzoom= (float)zoom / 100.0; *rwidth= fzoom * width; } index= (unsigned int *)lmalloc(sizeof(unsigned int) * *rwidth); for (a= 0; a < *rwidth; a++) if (zoom) *(index + a)= (float)a / fzoom; else *(index + a)= a; return(index); } Image *zoom(oimage, xzoom, yzoom, verbose) Image *oimage; float xzoom, yzoom; { char buf[BUFSIZ]; Image *image=NULL; unsigned int *xindex, *yindex; unsigned int xwidth, ywidth; unsigned int x, y, xsrc, ysrc; unsigned int pixlen; unsigned int srclinelen; unsigned int destlinelen; byte *srcline, *srcptr; byte *destline, *destptr; byte srcmask, destmask, bit; Pixel value; goodImage(oimage, "zoom"); if ((xzoom == 0.0) && (yzoom == 0.0)) /* stupid user */ return(NULL); if (xzoom == 0.0) { if (verbose) fprintf(stderr, " Zooming image Y axis by %0.2f%%...", yzoom); if (oimage->title) sprintf(buf, "%s (Y zoom %0.2f%%)", oimage->title, yzoom); } else if (yzoom == 0.0) { if (verbose) fprintf(stderr, " Zooming image X axis by %0.2f%%...", xzoom); if (oimage->title) sprintf(buf, "%s (X zoom %0.2f%%)", oimage->title, xzoom); } else if (xzoom == yzoom) { if (verbose) fprintf(stderr, " Zooming image by %0.2f%%...", xzoom); if (oimage->title) sprintf(buf, "%s (%d%% zoom)", oimage->title, xzoom); } else { if (verbose) fprintf(stderr, " Zooming image X axis by %0.2f%% and Y axis by %0.2f%%...", xzoom, yzoom); if (oimage->title) sprintf(buf, "%s (X zoom %0.2f%% Y zoom %0.2f%%)", oimage->title, xzoom, yzoom); } if (verbose) fflush(stderr); xindex= buildIndex(oimage->width, xzoom, &xwidth); yindex= buildIndex(oimage->height, yzoom, &ywidth); switch (oimage->type) { case IBITMAP: image= newBitImage(xwidth, ywidth); for (x= 0; x < oimage->rgb.used; x++) { *(image->rgb.red + x)= *(oimage->rgb.red + x); *(image->rgb.green + x)= *(oimage->rgb.green + x); *(image->rgb.blue + x)= *(oimage->rgb.blue + x); } image->rgb.used= oimage->rgb.used; destline= image->data; destlinelen= (xwidth / 8) + (xwidth % 8 ? 1 : 0); srcline= oimage->data; srclinelen= (oimage->width / 8) + (oimage->width % 8 ? 1 : 0); for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) { while (ysrc != *(yindex + y)) { ysrc++; srcline += srclinelen; } srcptr= srcline; destptr= destline; srcmask= 0x80; destmask= 0x80; bit= srcmask & *srcptr; for (x= 0, xsrc= *(xindex + x); x < xwidth; x++) { if (xsrc != *(xindex + x)) { do { xsrc++; if (!(srcmask >>= 1)) { srcmask= 0x80; srcptr++; } } while (xsrc != *(xindex + x)); bit= srcmask & *srcptr; } if (bit) *destptr |= destmask; if (!(destmask >>= 1)) { destmask= 0x80; destptr++; } } destline += destlinelen; } break; case IRGB: image= newRGBImage(xwidth, ywidth, oimage->depth); for (x= 0; x < oimage->rgb.used; x++) { *(image->rgb.red + x)= *(oimage->rgb.red + x); *(image->rgb.green + x)= *(oimage->rgb.green + x); *(image->rgb.blue + x)= *(oimage->rgb.blue + x); } image->rgb.used= oimage->rgb.used; /* FALLTHRU */ case ITRUE: if (!RGBP(oimage)) image= newTrueImage(xwidth, ywidth); pixlen= oimage->pixlen; destptr= image->data; srcline= oimage->data; srclinelen= oimage->width * pixlen; for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) { while (ysrc != *(yindex + y)) { ysrc++; srcline += srclinelen; } srcptr= srcline; value= memToVal(srcptr, pixlen); for (x= 0, xsrc= *(xindex + x); x < xwidth; x++) { if (xsrc != *(xindex + x)) { do { xsrc++; srcptr += image->pixlen; } while (xsrc != *(xindex + x)); value= memToVal(srcptr, pixlen); } valToMem(value, destptr, pixlen); destptr += pixlen; } } break; } if (image) { image->title= dupString(buf); image->trans = oimage->trans; } lfree((byte *)xindex); lfree((byte *)yindex); if (verbose) fprintf(stderr, "done\n"); return(image); }