Thu, 27 Dec 2001 11:04:43 +0000
Initial revision
eric@2 | 1 | #include <stdlib.h> |
eric@2 | 2 | |
eric@2 | 3 | #include "bitblt.h" |
eric@2 | 4 | |
eric@2 | 5 | static inline u8 pixel_mask (x) |
eric@2 | 6 | { |
eric@2 | 7 | #ifdef LSB_LEFT |
eric@2 | 8 | return (1 << x); |
eric@2 | 9 | #else |
eric@2 | 10 | return (1 << (7 - x)); |
eric@2 | 11 | #endif |
eric@2 | 12 | } |
eric@2 | 13 | |
eric@2 | 14 | static inline u32 rect_width (Rect r) |
eric@2 | 15 | { |
eric@2 | 16 | return (r.lower_right.x - r.upper_left.x); |
eric@2 | 17 | } |
eric@2 | 18 | |
eric@2 | 19 | static inline u32 rect_height (Rect r) |
eric@2 | 20 | { |
eric@2 | 21 | return (r.lower_right.y - r.upper_left.y); |
eric@2 | 22 | } |
eric@2 | 23 | |
eric@2 | 24 | Bitmap *create_bitmap (u32 width, u32 height) |
eric@2 | 25 | { |
eric@2 | 26 | Bitmap *bitmap; |
eric@2 | 27 | |
eric@2 | 28 | bitmap = calloc (1, sizeof (Bitmap)); |
eric@2 | 29 | if (! bitmap) |
eric@2 | 30 | return (NULL); |
eric@2 | 31 | bitmap->width = width; |
eric@2 | 32 | bitmap->height = height; |
eric@2 | 33 | bitmap->rowbytes = (width - 1) / 8 + 1; |
eric@2 | 34 | bitmap->bits = calloc (height * bitmap->rowbytes, 1); |
eric@2 | 35 | if (! bitmap->bits) |
eric@2 | 36 | { |
eric@2 | 37 | free (bitmap); |
eric@2 | 38 | return (NULL); |
eric@2 | 39 | } |
eric@2 | 40 | return (bitmap); |
eric@2 | 41 | } |
eric@2 | 42 | |
eric@2 | 43 | void free_bitmap (Bitmap *bitmap) |
eric@2 | 44 | { |
eric@2 | 45 | free (bitmap->bits); |
eric@2 | 46 | free (bitmap); |
eric@2 | 47 | } |
eric@2 | 48 | |
eric@2 | 49 | boolean get_pixel (Bitmap *bitmap, Point coord) |
eric@2 | 50 | { |
eric@2 | 51 | u8 *p; |
eric@2 | 52 | if ((coord.x >= bitmap->width) || (coord.y >= bitmap->height)) |
eric@2 | 53 | return (0); |
eric@2 | 54 | p = bitmap->bits + coord.y * bitmap->rowbytes + coord.x / 8; |
eric@2 | 55 | return ((*p & pixel_mask (coord.x & 7)) != 0); |
eric@2 | 56 | } |
eric@2 | 57 | |
eric@2 | 58 | void set_pixel (Bitmap *bitmap, Point coord, boolean value) |
eric@2 | 59 | { |
eric@2 | 60 | u8 *p; |
eric@2 | 61 | if ((coord.x >= bitmap->width) || (coord.y >= bitmap->height)) |
eric@2 | 62 | return; |
eric@2 | 63 | p = bitmap->bits + coord.y * bitmap->rowbytes + coord.x / 8; |
eric@2 | 64 | if (value) |
eric@2 | 65 | *p |= pixel_mask (coord.x & 7); |
eric@2 | 66 | else |
eric@2 | 67 | *p &= (0xff ^ pixel_mask (coord.x & 7)); |
eric@2 | 68 | } |
eric@2 | 69 | |
eric@2 | 70 | |
eric@2 | 71 | Bitmap *bitblt (Bitmap *src_bitmap, |
eric@2 | 72 | Rect src_rect, |
eric@2 | 73 | Bitmap *dest_bitmap, |
eric@2 | 74 | Point dest_upper_left, |
eric@2 | 75 | boolean flip_horizontal, |
eric@2 | 76 | boolean flip_vertical, |
eric@2 | 77 | boolean transpose, |
eric@2 | 78 | int tfn) |
eric@2 | 79 | { |
eric@2 | 80 | Point src_point, dest_point; |
eric@2 | 81 | boolean src_pixel, dest_pixel; |
eric@2 | 82 | |
eric@2 | 83 | if (! dest_bitmap) |
eric@2 | 84 | { |
eric@2 | 85 | if (transpose) |
eric@2 | 86 | dest_bitmap = create_bitmap (rect_height (src_rect), |
eric@2 | 87 | rect_width (src_rect)); |
eric@2 | 88 | else |
eric@2 | 89 | dest_bitmap = create_bitmap (rect_width (src_rect), |
eric@2 | 90 | rect_height (src_rect)); |
eric@2 | 91 | if (! dest_bitmap) |
eric@2 | 92 | return (NULL); |
eric@2 | 93 | } |
eric@2 | 94 | |
eric@2 | 95 | for (src_point.y = src_rect.upper_left.y; |
eric@2 | 96 | src_point.y < src_rect.lower_right.y; |
eric@2 | 97 | src_point.y++) |
eric@2 | 98 | { |
eric@2 | 99 | for (src_point.x = src_rect.upper_left.x; |
eric@2 | 100 | src_point.x < src_rect.lower_right.x; |
eric@2 | 101 | src_point.x++) |
eric@2 | 102 | { |
eric@2 | 103 | boolean a, b, c; |
eric@2 | 104 | |
eric@2 | 105 | if (transpose) |
eric@2 | 106 | { |
eric@2 | 107 | dest_point.x = dest_upper_left.x + (src_point.y - src_rect.upper_left.y); |
eric@2 | 108 | dest_point.y = dest_upper_left.y + (src_point.x - src_rect.upper_left.x); |
eric@2 | 109 | } |
eric@2 | 110 | else |
eric@2 | 111 | { |
eric@2 | 112 | dest_point.x = dest_upper_left.x + (src_point.x - src_rect.upper_left.x); |
eric@2 | 113 | dest_point.y = dest_upper_left.y + (src_point.y - src_rect.upper_left.y); |
eric@2 | 114 | } |
eric@2 | 115 | |
eric@2 | 116 | a = get_pixel (src_bitmap, src_point); |
eric@2 | 117 | b = get_pixel (dest_bitmap, dest_point); |
eric@2 | 118 | c = (tfn & (1 << (a * 2 + b))) != 0; |
eric@2 | 119 | |
eric@2 | 120 | set_pixel (dest_bitmap, dest_point, c); |
eric@2 | 121 | } |
eric@2 | 122 | } |
eric@2 | 123 | return (dest_bitmap); |
eric@2 | 124 | } |