static Image::Sampled *in_tga_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) { Image::Sampled *ret=0; bitmap_type bitmap=tga_load_image(((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false)); /* Imp: Work without duplicated memory allocation */ if (BITMAP_PLANES(bitmap)==1) { Image::Gray *img=new Image::Gray(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); ret=img; } else if (BITMAP_PLANES(bitmap)==3) { Image::RGB *img=new Image::RGB(BITMAP_WIDTH(bitmap), BITMAP_HEIGHT(bitmap), 8); memcpy(img->getRowbeg(), BITMAP_BITS(bitmap), (slen_t)3*BITMAP_WIDTH(bitmap)*BITMAP_HEIGHT(bitmap)); ret=img; } else assert(0 && "invalid TGA depth"); delete [] BITMAP_BITS(bitmap); return ret; }
static void filter_once (bitmap_type b) { unsigned row, col; unsigned all_black = SQUARE (2 * filter_size + 1) - 1; unsigned t = filter_threshold * all_black; /* Rounded threshold. */ /* For each pixel in the bitmap... */ for (row = filter_size; row < BITMAP_HEIGHT (b) - filter_size; row++) for (col = filter_size; col < BITMAP_WIDTH (b) - filter_size; col++) { int cell_row, cell_col; unsigned sum = 0; /* For each pixel in the cell... */ for (cell_row = -filter_size; cell_row <= filter_size; cell_row++) for (cell_col = -filter_size; cell_col <= filter_size; cell_col++) { /*assert (VALID_LOCATION (b, row + cell_row, col + cell_col));*/ /* If center pixel, don't do anything. */ if (cell_row != 0 || cell_col != 0) sum += BITMAP_PIXEL (b, row + cell_row, col + cell_col); } /* We've computed the sum of the neighbors. Now change the pixel if the difference is greater than the threshold. Doing integer arithmetic is not as precise as floating point (since the threshold is rounded), but it's much faster. */ if (abs (sum - (all_black * BITMAP_PIXEL (b, row, col))) > t) BITMAP_PIXEL (b, row, col) = ((double) sum) / all_black; } }
static bitmap_type local_new_bitmap (unsigned width,unsigned height) { bitmap_type answer; unsigned size = width * height; BITMAP_HEIGHT(answer) = height; BITMAP_WIDTH(answer) = width; BITMAP_BITS (answer) = g_new0 (one_byte, size); /* g_new returns NULL if size == 0 */ /* printf("local_new_bitmap size = %d @[%p]\n",size,BITMAP_BITS (answer)); */ return answer; }
/* Put B2 to the right of B1, changing B1. For example, if B1 looked like `A' and B2 like `B', the result would look like `AB'. The two bitmaps must have the same number of rows. */ void bitmap_concat (bitmap_type *b1, bitmap_type b2) { bitmap_type new; dimensions_type new_dimens; unsigned row; assert (BITMAP_HEIGHT (*b1) == BITMAP_HEIGHT (b2)); DIMENSIONS_WIDTH (new_dimens) = BITMAP_WIDTH (*b1) + BITMAP_WIDTH (b2); DIMENSIONS_HEIGHT (new_dimens) = BITMAP_HEIGHT (b2); new = new_bitmap (new_dimens); for (row = 0; row < BITMAP_HEIGHT (b2); row++) { one_byte *target1 = BITMAP_ROW (new, row); one_byte *target2 = target1 + BITMAP_WIDTH (*b1); memcpy (target1, BITMAP_ROW (*b1, row), BITMAP_WIDTH (*b1)); memcpy (target2, BITMAP_ROW (b2, row), BITMAP_WIDTH (b2)); } free_bitmap (b1); *b1 = new; }
/* Free afterwards; see revert_command. */ free_bitmap (b); } /* Expand the bitmap B by one pixel on all four sides. We return a new bitmap. */ static bitmap_type enlarge_bitmap (bitmap_type b) { bitmap_type new; dimensions_type new_size; unsigned row; DIMENSIONS_WIDTH (new_size) = BITMAP_WIDTH (b) + 2; DIMENSIONS_HEIGHT (new_size) = BITMAP_HEIGHT (b) + 2; new = new_bitmap (new_size); /* `new_bitmap' initializes all the pixels to white, so we don't have to do anything to the new rows and columns. */ for (row = 1; row < DIMENSIONS_HEIGHT (new_size) - 1; row++) { one_byte *source = BITMAP_ROW (b, row - 1); one_byte *target = BITMAP_ROW (new, row) + 1; memcpy (target, source, BITMAP_WIDTH (b)); } return new;