X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/d5477d3d0bc40d154ff61827dbc68f2343171772..e1c0692925:/SGI/imsgi.c diff --git a/SGI/imsgi.c b/SGI/imsgi.c index afc4d87f..f6ad1b57 100644 --- a/SGI/imsgi.c +++ b/SGI/imsgi.c @@ -20,6 +20,9 @@ /* we add that little bit to avoid rounding issues */ #define SampleFTo16(num) ((int)((num) * 65535.0 + 0.01)) +/* maximum size of an SGI image */ +#define SGI_DIM_LIMIT 0xFFFF + typedef struct { unsigned short imagic; unsigned char storagetype; @@ -121,7 +124,7 @@ store_16(unsigned char *buf, unsigned short value) { } static void -store_32(unsigned char *buf, unsigned short value) { +store_32(unsigned char *buf, unsigned long value) { buf[0] = value >> 24; buf[1] = (value >> 16) & 0xFF; buf[2] = (value >> 8) & 0xFF; @@ -179,7 +182,7 @@ i_readsgi_wiol(io_glue *ig, int partial) { mm_log((1,"i_readsgi(ig %p, partial %d)\n", ig, partial)); i_clear_error(); - if (ig->readcb(ig, headbuf, 512) != 512) { + if (i_io_read(ig, headbuf, 512) != 512) { i_push_error(errno, "SGI image: could not read header"); return NULL; } @@ -325,6 +328,11 @@ i_writesgi_wiol(io_glue *ig, i_img *img) { i_clear_error(); + if (img->xsize > SGI_DIM_LIMIT || img->ysize > SGI_DIM_LIMIT) { + i_push_error(0, "image too large for SGI"); + return 0; + } + if (!write_sgi_header(img, ig, &rle, &bpc2)) return 0; @@ -367,7 +375,7 @@ read_rgb_8_verbatim(i_img *img, io_glue *ig, rgb_header const *header) { for(y = 0; y < height; y++) { int x; - if (ig->readcb(ig, databuf, width) != width) { + if (i_io_read(ig, databuf, width) != width) { i_push_error(0, "SGI image: cannot read image data"); i_img_destroy(img); myfree(linebuf); @@ -428,32 +436,32 @@ read_rle_tables(io_glue *ig, i_img *img, length_tab = mymalloc(height*channels*sizeof(unsigned long)); /* Read offset table */ - if (ig->readcb(ig, databuf, height * channels * 4) != height * channels * 4) { + if (i_io_read(ig, databuf, height * channels * 4) != height * channels * 4) { i_push_error(0, "SGI image: short read reading RLE start table"); goto ErrorReturn; } for(i = 0; i < height * channels; i++) - start_tab[i] = (databuf[i*4] << 24) | (databuf[i*4+1] << 16) | + start_tab[i] = ((unsigned long)databuf[i*4] << 24) | (databuf[i*4+1] << 16) | (databuf[i*4+2] << 8) | (databuf[i*4+3]); /* Read length table */ - if (ig->readcb(ig, databuf, height*channels*4) != height*channels*4) { + if (i_io_read(ig, databuf, height*channels*4) != height*channels*4) { i_push_error(0, "SGI image: short read reading RLE length table"); goto ErrorReturn; } for(i=0; i < height * channels; i++) { - length_tab[i] = (databuf[i*4] << 24) + (databuf[i*4+1] << 16)+ - (databuf[i*4+2] << 8) + (databuf[i*4+3]); + length_tab[i] = ((unsigned long)databuf[i*4] << 24) | (databuf[i*4+1] << 16) | + (databuf[i*4+2] << 8) | (databuf[i*4+3]); if (length_tab[i] > max_length) max_length = length_tab[i]; } mm_log((3, "Offset/length table:\n")); for(i=0; i < height * channels; i++) - mm_log((3, "%d: %d/%d\n", i, start_tab[i], length_tab[i])); + mm_log((3, "%d: %lu/%lu\n", i, start_tab[i], length_tab[i])); *pstart_tab = start_tab; *plength_tab = length_tab; @@ -479,7 +487,7 @@ read_rgb_8_rle(i_img *img, io_glue *ig, rgb_header const *header) { unsigned long max_length; i_img_dim width = i_img_get_width(img); i_img_dim height = i_img_get_height(img); - int channels = i_img_getchannels(img);; + int channels = i_img_getchannels(img); i_img_dim y; int c; int pixmin = header->pixmin; @@ -492,7 +500,7 @@ read_rgb_8_rle(i_img *img, io_glue *ig, rgb_header const *header) { return NULL; } - mm_log((1, "maxlen for an rle buffer: %d\n", max_length)); + mm_log((1, "maxlen for an rle buffer: %lu\n", max_length)); if (max_length > (img->xsize + 1) * 2) { i_push_errorf(0, "SGI image: ridiculous RLE line length %lu", max_length); @@ -512,11 +520,11 @@ read_rgb_8_rle(i_img *img, io_glue *ig, rgb_header const *header) { int pixels_left = width; i_sample_t sample; - if (ig->seekcb(ig, start_tab[ci], SEEK_SET) != start_tab[ci]) { + if (i_io_seek(ig, start_tab[ci], SEEK_SET) != start_tab[ci]) { i_push_error(0, "SGI image: cannot seek to RLE data"); goto ErrorReturn; } - if (ig->readcb(ig, databuf, datalen) != datalen) { + if (i_io_read(ig, databuf, datalen) != datalen) { i_push_error(0, "SGI image: cannot read RLE data"); goto ErrorReturn; } @@ -568,7 +576,7 @@ read_rgb_8_rle(i_img *img, io_glue *ig, rgb_header const *header) { /* RLE run */ if (count > pixels_left) { i_push_error(0, "SGI image: RLE run overflows scanline"); - mm_log((2, "RLE run overflows scanline (y %d chan %d offset %ld len %ld)\n", y, c, start_tab[ci], length_tab[ci])); + mm_log((2, "RLE run overflows scanline (y %" i_DF " chan %d offset %lu len %lu)\n", i_DFc(y), c, start_tab[ci], length_tab[ci])); goto ErrorReturn; } if (data_left < 1) { @@ -648,7 +656,7 @@ read_rgb_16_verbatim(i_img *img, io_glue *ig, rgb_header const *header) { for(y = 0; y < height; y++) { int x; - if (ig->readcb(ig, databuf, width*2) != width*2) { + if (i_io_read(ig, databuf, width*2) != width*2) { i_push_error(0, "SGI image: cannot read image data"); i_img_destroy(img); myfree(linebuf); @@ -693,7 +701,7 @@ read_rgb_16_rle(i_img *img, io_glue *ig, rgb_header const *header) { unsigned long max_length; i_img_dim width = i_img_get_width(img); i_img_dim height = i_img_get_height(img); - int channels = i_img_getchannels(img);; + int channels = i_img_getchannels(img); i_img_dim y; int c; int pixmin = header->pixmin; @@ -730,11 +738,11 @@ read_rgb_16_rle(i_img *img, io_glue *ig, rgb_header const *header) { i_push_error(0, "SGI image: invalid RLE length value for BPC=2"); goto ErrorReturn; } - if (ig->seekcb(ig, start_tab[ci], SEEK_SET) != start_tab[ci]) { + if (i_io_seek(ig, start_tab[ci], SEEK_SET) != start_tab[ci]) { i_push_error(0, "SGI image: cannot seek to RLE data"); goto ErrorReturn; } - if (ig->readcb(ig, databuf, datalen) != datalen) { + if (i_io_read(ig, databuf, datalen) != datalen) { i_push_error(0, "SGI image: cannot read RLE data"); goto ErrorReturn; } @@ -904,7 +912,7 @@ write_sgi_8_verb(i_img *img, io_glue *ig) { for (c = 0; c < img->channels; ++c) { for (y = img->ysize - 1; y >= 0; --y) { i_gsamp(img, 0, width, y, linebuf, &c, 1); - if (ig->writecb(ig, linebuf, width) != width) { + if (i_io_write(ig, linebuf, width) != width) { i_push_error(errno, "SGI image: error writing image data"); myfree(linebuf); return 0; @@ -913,6 +921,9 @@ write_sgi_8_verb(i_img *img, io_glue *ig) { } myfree(linebuf); + if (i_io_close(ig)) + return 0; + return 1; } @@ -987,9 +998,8 @@ write_sgi_8_rle(i_img *img, io_glue *ig) { /* fill out the run if 2 or less samples left and there's space */ if (in_left - run_length <= 2 - && run_length + in_left - run_length <= 127) { - run_length += in_left; - in_left = 0; + && in_left <= 127) { + run_length = in_left; } in_left -= run_length; *outp++ = run_length | 0x80; @@ -1004,7 +1014,7 @@ write_sgi_8_rle(i_img *img, io_glue *ig) { store_32(lengths + offset_pos, comp_size); offset_pos += 4; current_offset += comp_size; - if (ig->writecb(ig, comp_buf, comp_size) != comp_size) { + if (i_io_write(ig, comp_buf, comp_size) != comp_size) { i_push_error(errno, "SGI image: error writing RLE data"); goto Error; } @@ -1026,6 +1036,9 @@ write_sgi_8_rle(i_img *img, io_glue *ig) { myfree(comp_buf); myfree(linebuf); + if (i_io_close(ig)) + return 0; + return 1; Error: @@ -1054,7 +1067,7 @@ write_sgi_16_verb(i_img *img, io_glue *ig) { unsigned short samp16 = SampleFTo16(linebuf[x]); store_16(outp, samp16); } - if (ig->writecb(ig, encbuf, width * 2) != width * 2) { + if (i_io_write(ig, encbuf, width * 2) != width * 2) { i_push_error(errno, "SGI image: error writing image data"); myfree(linebuf); myfree(encbuf); @@ -1065,6 +1078,9 @@ write_sgi_16_verb(i_img *img, io_glue *ig) { myfree(linebuf); myfree(encbuf); + if (i_io_close(ig)) + return 0; + return 1; } @@ -1145,9 +1161,8 @@ write_sgi_16_rle(i_img *img, io_glue *ig) { /* fill out the run if 2 or less samples left and there's space */ if (in_left - run_length <= 2 - && run_length + in_left - run_length <= 127) { - run_length += in_left; - in_left = 0; + && in_left <= 127) { + run_length = in_left; } in_left -= run_length; store_16(outp, run_length | 0x80); @@ -1165,7 +1180,7 @@ write_sgi_16_rle(i_img *img, io_glue *ig) { store_32(lengths + offset_pos, comp_size); offset_pos += 4; current_offset += comp_size; - if (ig->writecb(ig, comp_buf, comp_size) != comp_size) { + if (i_io_write(ig, comp_buf, comp_size) != comp_size) { i_push_error(errno, "SGI image: error writing RLE data"); goto Error; } @@ -1188,6 +1203,9 @@ write_sgi_16_rle(i_img *img, io_glue *ig) { myfree(linebuf); myfree(sampbuf); + if (i_io_close(ig)) + return 0; + return 1; Error: