MDJVU_IMPLEMENT void mdjvu_bitmap_assign(mdjvu_bitmap_t dst, mdjvu_bitmap_t b) { mdjvu_destroy_2d_array(((Bitmap *)dst)->data); ((Bitmap *)dst)->data = mdjvu_create_2d_array(BYTES_PER_ROW(BMP->width), BMP->height); ((Bitmap *)dst)->width = BMP->width; ((Bitmap *)dst)->height = BMP->height; memcpy(((Bitmap *) dst)->data[0], BMP->data[0], ROW_SIZE * BMP->height); }
MDJVU_IMPLEMENT void mdjvu_bitmap_destroy(mdjvu_bitmap_t bmp) { Bitmap *b = (Bitmap *) bmp; #ifndef NDEBUG alive_bitmap_counter--; #endif mdjvu_destroy_2d_array(b->data); free(b); }
mdjvu_pattern_t mdjvu_pattern_create(mdjvu_bitmap_t bitmap) { int32 w = mdjvu_bitmap_get_width(bitmap); int32 h = mdjvu_bitmap_get_height(bitmap); mdjvu_pattern_t pattern; byte **pixels = mdjvu_create_2d_array(w, h); mdjvu_bitmap_unpack_all(bitmap, pixels); pattern = mdjvu_pattern_create_from_array(pixels, w, h); mdjvu_destroy_2d_array(pixels); return pattern; }
static void add_to_image(mdjvu_image_t image, mdjvu_bitmap_t bitmap, int32 dpi, mdjvu_split_options_t opt, int32 blit_shift_x, int32 blit_shift_y, int big) { int32 max_shape_size = opt ? * (int32 *) opt : 0; int32 width = mdjvu_bitmap_get_width(bitmap); int32 height = mdjvu_bitmap_get_height(bitmap); unsigned char **buf, **window_base, **window_buf, **map; int32 window_shift = 0, y = 0, i; if (!max_shape_size) max_shape_size = dpi; if (max_shape_size > height) max_shape_size = height; /* n-th line will be unpacked into buf[n % max_shape_size] + 1. * ( +1 is to make the left margin) * buf[max_shape_size] will always be blank. * * window_base[window_shift - 1] * points to buf[max_shape_size] + 1 (blank line) - top margin * window_base[window_shift + max_shape_size] * points to buf[max_shape_size] + 1 (blank line) - bottom margin * window_base[window_shift + i] * points to buf[(window_shift + i) % max_shape_size] + 1. */ /* map has the right margin of 1 */ map = mdjvu_create_2d_array(width + 1, max_shape_size); /* buf has left, right and bottom margins of 1 */ buf = mdjvu_create_2d_array(width + 2, max_shape_size + 1); window_buf = (unsigned char **) malloc(2 * (max_shape_size + 2) * sizeof(unsigned char *)); window_base = window_buf + 1; /* Unpack initial portion of the bitmap; bind the window to the buffer */ for (i = 0; i < max_shape_size; i++) { window_base[i] = window_base[max_shape_size + i] = buf[i] + 1; mdjvu_bitmap_unpack_row(bitmap, buf[i] + 1, i); } /* Setup top and bottom white margins */ window_base[-1] = window_base[2 * max_shape_size - 1] = buf[max_shape_size] + 1; /* The "window moving" loop. * We're moving a (width x max_shape_size) window through the image. */ while(1) { /* Extract some shapes from the window * (shapes touching the topmost row will be affected). */ unsigned char *top_margin_save = /* make the top margin */ window_base[window_shift - 1]; /* (save what was there) */ unsigned char *bot_margin_save = /* same with the bottom margin */ window_base[window_shift + max_shape_size]; int32 old_window_shift; window_base[window_shift - 1] = buf[max_shape_size] + 1; /* clear them */ window_base[window_shift + max_shape_size] = buf[max_shape_size] + 1; process_row(window_base + window_shift, map, /* index of a row to process: */ 0, width, max_shape_size, image, 0, y, max_shape_size, blit_shift_x, blit_shift_y, dpi, opt, big); window_base[window_shift - 1] = top_margin_save; /* restore margins */ window_base[window_shift + max_shape_size] = bot_margin_save; /* Shift the window */ y++; old_window_shift = window_shift; window_shift = y % max_shape_size; if (y + max_shape_size > height) break; /* Unpack a new row into the bottom window row */ mdjvu_bitmap_unpack_row(bitmap, buf[old_window_shift] + 1, y + max_shape_size - 1); } /* Process the last window fully */ for (i = 0; y + i < height; i++) { process_row(window_base + window_shift, map, /* index of a row to process: */ i, width, max_shape_size, image, 0, y, max_shape_size, blit_shift_x, blit_shift_y, dpi, opt, big); } /* Clean up */ free(window_buf); mdjvu_destroy_2d_array(map); mdjvu_destroy_2d_array(buf); }