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