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