Code:
void image_rotate(int dim, pixel *src, pixel *dst)
{
int i, j;
for ( i = 0; i < dim; i++ )
{
for ( j = 0; j < dim; j+=4 )
{
dst[RIDX(dim-j-1, i, dim)] = src[RIDX(i, j+0, dim)];
dst[RIDX(dim-j+0, i, dim)] = src[RIDX(i, j+1, dim)];
dst[RIDX(dim-j+1, i, dim)] = src[RIDX(i, j+2, dim)];
dst[RIDX(dim-j+2, i, dim)] = src[RIDX(i, j+3, dim)];
}
}
}
Then run it through the preprocessor.
Code:
#include <stdio.h>
typedef int type;
void print(const type *array, int rows, int cols)
{
int i;
for ( i = 0; i < rows * cols; ++i )
{
printf("%3d%c", array[i], i % cols == cols - 1 ? '\n' : ' ');
}
putchar('\n');
fflush(stdout);
}
void rotate(type *dst, const type *src, int rows, int cols)
{
int r, c;
for ( r = 0; r < rows; ++r )
{
type *cell = dst + rows - 1 - r;
for ( c = 0; c < cols; ++c )
{
*cell = *src++;
cell += rows;
}
}
}
type image[] =
{
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,
};
type result [ sizeof image / sizeof *image ];
int main()
{
print(image, 10, 10);
rotate(result, image, 10, 10);
print(result, 10, 10);
print(image, 5, 20);
rotate(result, image, 5, 20);
print(result, 20, 5);
return 0;
}
/* my output
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
91 81 71 61 51 41 31 21 11 1
92 82 72 62 52 42 32 22 12 2
93 83 73 63 53 43 33 23 13 3
94 84 74 64 54 44 34 24 14 4
95 85 75 65 55 45 35 25 15 5
96 86 76 66 56 46 36 26 16 6
97 87 77 67 57 47 37 27 17 7
98 88 78 68 58 48 38 28 18 8
99 89 79 69 59 49 39 29 19 9
100 90 80 70 60 50 40 30 20 10
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
81 61 41 21 1
82 62 42 22 2
83 63 43 23 3
84 64 44 24 4
85 65 45 25 5
86 66 46 26 6
87 67 47 27 7
88 68 48 28 8
89 69 49 29 9
90 70 50 30 10
91 71 51 31 11
92 72 52 32 12
93 73 53 33 13
94 74 54 34 14
95 75 55 35 15
96 76 56 36 16
97 77 57 37 17
98 78 58 38 18
99 79 59 39 19
100 80 60 40 20
*/
[EDIT=6]One final thought: more loop invariant code (and a useful return value) might be handled like this.
Code:
type *rotate(type *dst, const type *src, int rows, int cols)
{
int r, c;
type *const col = dst + rows - 1;
for ( r = 0; r < rows; ++r )
{
type *cell = col - r;
for ( c = 0; c < cols; ++c )
{
*cell = *src++;
cell += rows;
}
}
return dst;
}
int main()
{
print(image, 10, 10);
print(rotate(result, image, 10, 10), 10, 10);
print(image, 5, 20);
print(rotate(result, image, 5, 20), 20, 5);
return 0;
}