if (!write_packed(ig, "CCVvvVVVVvvVVVVVV", 'B', 'M', data_size+offset,
0, 0, offset, INFOHEAD_SIZE, im->xsize, im->ysize, 1,
- bit_count, BI_RGB, 0, (int)(xres+0.5), (int)(yres+0.5),
+ bit_count, BI_RGB, data_size, (int)(xres+0.5), (int)(yres+0.5),
colors_used, colors_used)){
i_push_error(0, "cannot write bmp header");
return 0;
return 1;
}
-static int bgr_chans[] = { 2, 1, 0, };
-static int grey_chans[] = { 0, 0, 0, };
-
/*
=item write_24bit_data(ig, im)
*/
static int
write_24bit_data(io_glue *ig, i_img *im) {
- int *chans;
unsigned char *samples;
int y;
int line_size = 3 * im->xsize;
+ i_color bg;
+
+ i_get_file_background(im, &bg);
/* just in case we implement a direct format with 2bytes/pixel
(unlikely though) */
if (!write_bmphead(ig, im, 24, line_size * im->ysize))
return 0;
- chans = im->channels >= 3 ? bgr_chans : grey_chans;
- samples = mymalloc(line_size); /* checked 29jun05 tonyc */
+ samples = mymalloc(4 * im->xsize);
memset(samples, 0, line_size);
for (y = im->ysize-1; y >= 0; --y) {
- i_gsamp(im, 0, im->xsize, y, samples, chans, 3);
+ unsigned char *samplep = samples;
+ int x;
+ i_gsamp_bg(im, 0, im->xsize, y, samples, 3, &bg);
+ for (x = 0; x < im->xsize; ++x) {
+ unsigned char tmp = samplep[2];
+ samplep[2] = samplep[0];
+ samplep[0] = tmp;
+ samplep += 3;
+ }
if (ig->writecb(ig, samples, line_size) < 0) {
i_push_error(0, "writing image data");
myfree(samples);
}
}
else if (packed[0]) {
+ if (x + packed[0] > xsize) {
+ /* this file is corrupt */
+ myfree(packed);
+ myfree(line);
+ i_push_error(0, "invalid data during decompression");
+ i_img_destroy(im);
+ return NULL;
+ }
line[0] = packed[1] >> 4;
line[1] = packed[1] & 0x0F;
for (i = 0; i < packed[0]; i += 2) {
default:
count = packed[1];
+ if (x + count > xsize) {
+ /* this file is corrupt */
+ myfree(packed);
+ myfree(line);
+ i_push_error(0, "invalid data during decompression");
+ i_img_destroy(im);
+ return NULL;
+ }
size = (count + 1) / 2;
read_size = (size+1) / 2 * 2;
if (ig->readcb(ig, packed, read_size) != read_size) {
}
}
if (packed[0]) {
+ if (x + packed[0] > xsize) {
+ /* this file isn't incomplete, it's corrupt */
+ myfree(line);
+ i_push_error(0, "invalid data during decompression");
+ i_img_destroy(im);
+ return NULL;
+ }
memset(line, packed[1], packed[0]);
i_ppal(im, x, x+packed[0], y, line);
x += packed[0];
default:
count = packed[1];
+ if (x + count > xsize) {
+ /* runs shouldn't cross a line boundary */
+ /* this file isn't incomplete, it's corrupt */
+ myfree(line);
+ i_push_error(0, "invalid data during decompression");
+ i_img_destroy(im);
+ return NULL;
+ }
read_size = (count+1) / 2 * 2;
if (ig->readcb(ig, line, read_size) != read_size) {
myfree(line);