home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xloadimg.zip / xloadimage.4.1 / rotate.c < prev    next >
C/C++ Source or Header  |  1993-10-21  |  4KB  |  147 lines

  1. /* rotate.c
  2.  *
  3.  * rotate an image
  4.  *
  5.  * Contributed by Tom Tatlow (tatlow@dash.enet.dec.com)
  6.  */
  7.  
  8. #include "copyright.h"
  9. #include "image.h"
  10.  
  11. /* rotate_bitmap()
  12.  * converts an old bitmap bit position into a new one
  13.  */
  14. void rotate_bitmap(num, pos, width, height, new_num, new_pos)
  15. int      num;                /* Source byte number       */
  16. int      pos;                /* Source bit position      */
  17. int    width;                /* Width of source bitmap   */
  18. int   height;                /* Height of source bitmap  */
  19. int *new_num;                /* Destination byte number  */
  20. int *new_pos;                /* Destination bit position */
  21. {
  22.   int   slen;                /* Length of source line      */
  23.   int   dlen;                /* Length of destination line */
  24.   int sx, sy;
  25.   int dx, dy;
  26.  
  27.   slen = (width / 8) + (width % 8 ? 1 : 0);
  28.   dlen = (height / 8) + (height % 8 ? 1 : 0);
  29.   sy = num / slen;
  30.   sx = ((num - (sy * slen)) * 8) + pos;
  31.   dx = (height - sy) - 1;
  32.   dy = sx;
  33.   *new_num = (dx / 8) + (dy * dlen);
  34.   *new_pos = dx % 8;
  35. }
  36.  
  37. /* rotate()
  38.  * rotates an image
  39.  */
  40. Image *rotate(simage, degrees, verbose)
  41. Image *simage;                /* Image to rotate             */
  42. unsigned int degrees;            /* Number of degrees to rotate */
  43. unsigned int verbose;
  44.   char buf[BUFSIZ];            /* New title                   */
  45.   Image    *image1;            /* Source image                */
  46.   Image    *image2;            /* Destination image           */
  47.   byte         *sp;            /* Pointer to source data      */
  48.   byte         *dp;            /* Pointer to destination data */
  49.   int     slinelen;            /* Length of source line       */
  50.   int     dlinelen;            /* Length of destination line  */
  51.   int       bit[8];            /* Array of hex values         */
  52.   int         x, y;
  53.   int         i, b;
  54.   int   newx, newy;
  55.   int   newi, newb;
  56.   byte      **yptr;
  57.  
  58.   bit[0] = 128;
  59.   bit[1] =  64;
  60.   bit[2] =  32;
  61.   bit[3] =  16;
  62.   bit[4] =   8;
  63.   bit[5] =   4;
  64.   bit[6] =   2;
  65.   bit[7] =   1;
  66.  
  67.   goodImage(simage, "rotate");
  68.  
  69.   if (verbose)
  70.     { printf("  Rotating image by %d degrees...", degrees);
  71.       fflush(stdout);
  72.     }
  73.   sprintf(buf, "%s (rotated by %d degrees)", simage->title, degrees);
  74.  
  75.   image1 = simage;
  76.   do {
  77.     degrees -= 90;
  78.     switch (image1->type) {
  79.     case IBITMAP:
  80.       image2= newBitImage(image1->height, image1->width);
  81.       for (x= 0; x < image1->rgb.used; x++) {
  82.     *(image2->rgb.red + x)= *(image1->rgb.red + x);
  83.     *(image2->rgb.green + x)= *(image1->rgb.green + x);
  84.     *(image2->rgb.blue + x)= *(image1->rgb.blue + x);
  85.       }
  86.       slinelen= (image1->width / 8) + (image1->width % 8 ? 1 : 0);
  87.       sp = image1->data;
  88.       dp = image2->data;
  89.       for (i = 0; i < (slinelen * image1->height); i++)
  90.     for (b = 0; b < 8; b++)
  91.       if (sp[i] & bit[b])
  92.         { rotate_bitmap(i, b, image1->width, image1->height, &newi, &newb);
  93.           dp[newi] |= bit[newb];
  94.         }
  95.       break;
  96.       
  97.     case IRGB:
  98.       image2= newRGBImage(image1->height, image1->width, image1->depth);
  99.       for (x= 0; x < image1->rgb.used; x++) {
  100.     *(image2->rgb.red + x)= *(image1->rgb.red + x);
  101.     *(image2->rgb.green + x)= *(image1->rgb.green + x);
  102.     *(image2->rgb.blue + x)= *(image1->rgb.blue + x);
  103.       }
  104.       image2->rgb.used= image1->rgb.used;
  105.       /* FALLTHRU */
  106.  
  107.     case ITRUE:
  108.       if (TRUEP(image1))
  109.     image2= newTrueImage(image1->height, image1->width);
  110.  
  111.       /* build array of y axis ptrs into destination image
  112.        */
  113.  
  114.       yptr= (byte **)lmalloc(image1->width * sizeof(char *));
  115.       dlinelen= image1->height * image1->pixlen;
  116.       for (y= 0; y < image1->width; y++)
  117.     yptr[y]= image2->data + (y * dlinelen);
  118.  
  119.       /* rotate
  120.        */
  121.  
  122.       sp= image1->data;
  123.       for (y = 0; y < image1->height; y++)
  124.     for (x = 0; x < image1->width; x++) {
  125.       valToMem(memToVal(sp, image1->pixlen),
  126.            yptr[x] + ((image1->height - y - 1) * image1->pixlen),
  127.            image1->pixlen);
  128.       sp += image1->pixlen;
  129.     }
  130.       lfree((byte *)yptr);
  131.       break;
  132.     default:
  133.       printf("rotate: Unsupported image type\n");
  134.       exit(1);
  135.     }
  136.     if (image1 != simage)
  137.       freeImage(image1);
  138.     image1 = image2;
  139.   } while (degrees);
  140.   image1->title= dupString(buf);
  141.   if (verbose)
  142.     printf("done\n");
  143.   return(image1);
  144. }
  145.  
  146.