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