/* 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;
}
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;
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;
}
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;
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);
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;
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);
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;
}
/* 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) {
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);
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;
}
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;
}
myfree(linebuf);
+ if (i_io_close(ig))
+ return 0;
+
return 1;
}
/* 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;
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;
}
myfree(comp_buf);
myfree(linebuf);
+ if (i_io_close(ig))
+ return 0;
+
return 1;
Error:
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);
myfree(linebuf);
myfree(encbuf);
+ if (i_io_close(ig))
+ return 0;
+
return 1;
}
/* 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);
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;
}
myfree(linebuf);
myfree(sampbuf);
+ if (i_io_close(ig))
+ return 0;
+
return 1;
Error: