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  */
rotate_bitmap(num,pos,width,height,new_num,new_pos)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  */
rotate(simage,degrees,verbose)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 {
45   char buf[BUFSIZ];			/* New title                   */
46   Image    *image1;			/* Source image                */
47   Image    *image2;			/* Destination image           */
48   byte         *sp;			/* Pointer to source data      */
49   byte         *dp;			/* Pointer to destination data */
50   int     slinelen;			/* Length of source line       */
51   int     dlinelen;			/* Length of destination line  */
52   int       bit[8];			/* Array of hex values         */
53   int         x, y;
54   int         i, b;
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   snprintf(buf, BUFSIZ - 1, "%s (rotated by %d degrees)", simage->title, degrees);
74 
75   image1 = simage;
76   image2 = NULL;
77   do {
78     degrees -= 90;
79     switch (image1->type) {
80     case IBITMAP:
81       image2= newBitImage(image1->height, image1->width);
82       for (x= 0; x < image1->rgb.used; x++) {
83 	*(image2->rgb.red + x)= *(image1->rgb.red + x);
84 	*(image2->rgb.green + x)= *(image1->rgb.green + x);
85 	*(image2->rgb.blue + x)= *(image1->rgb.blue + x);
86       }
87       slinelen= (image1->width / 8) + (image1->width % 8 ? 1 : 0);
88       sp = image1->data;
89       dp = image2->data;
90       for (i = 0; i < (slinelen * image1->height); i++)
91 	for (b = 0; b < 8; b++)
92 	  if (sp[i] & bit[b])
93 	    { rotate_bitmap(i, b, image1->width, image1->height, &newi, &newb);
94 	      dp[newi] |= bit[newb];
95 	    }
96       break;
97 
98     case IRGB:
99       image2= newRGBImage(image1->height, image1->width, image1->depth);
100       for (x= 0; x < image1->rgb.used; x++) {
101 	*(image2->rgb.red + x)= *(image1->rgb.red + x);
102 	*(image2->rgb.green + x)= *(image1->rgb.green + x);
103 	*(image2->rgb.blue + x)= *(image1->rgb.blue + x);
104       }
105       image2->rgb.used= image1->rgb.used;
106       /* FALLTHRU */
107 
108     case ITRUE:
109       if (TRUEP(image1))
110 	image2= newTrueImage(image1->height, image1->width);
111 
112       /* build array of y axis ptrs into destination image
113        */
114 
115       yptr= (byte **)lmalloc(image1->width * sizeof(char *));
116       dlinelen= image1->height * image1->pixlen;
117       for (y= 0; y < image1->width; y++)
118 	yptr[y]= image2->data + (y * dlinelen);
119 
120       /* rotate
121        */
122 
123       sp= image1->data;
124       for (y = 0; y < image1->height; y++)
125 	for (x = 0; x < image1->width; x++) {
126 	  valToMem(memToVal(sp, image1->pixlen),
127 		   yptr[x] + ((image1->height - y - 1) * image1->pixlen),
128 		   image1->pixlen);
129 	  sp += image1->pixlen;
130 	}
131       lfree((byte *)yptr);
132       break;
133     default:
134       printf("rotate: Unsupported image type\n");
135       exit(1);
136     }
137     if (image1 != simage)
138       freeImage(image1);
139     image1 = image2;
140   } while (degrees);
141   image1->title= dupString(buf);
142   if (verbose)
143     printf("done\n");
144   return(image1);
145 }
146 
147