-#include "image.h"
-#include "io.h"
+#include "imagei.h"
#include "log.h"
#include "iolayer.h"
Some of these functions are internal.
-=over 4
+=over
=cut
*/
typedef struct {
- char idlength;
+ unsigned char idlength;
char colourmaptype;
char datatypecode;
short int colourmaporigin;
val->rgba.r = buf[2];
val->rgba.a = buf[3];
break;
- default:
}
}
buf[2] = val->rgba.r;
buf[3] = val->rgba.a;
break;
- default:
}
}
}
+/* this function should never produce diagnostics to stdout, maybe to the logfile */
+int
+tga_header_verify(unsigned char headbuf[18]) {
+ tga_header header;
+ tga_header_unpack(&header, headbuf);
+ switch (header.datatypecode) {
+ default:
+ /*printf("bad typecode!\n");*/
+ return 0;
+ case 0:
+ case 1: /* Uncompressed, color-mapped images */
+ case 2: /* Uncompressed, rgb images */
+ case 3: /* Uncompressed, grayscale images */
+ case 9: /* Compressed, color-mapped images */
+ case 10: /* Compressed, rgb images */
+ case 11: /* Compressed, grayscale images */
+ break;
+ }
+
+ switch (header.colourmaptype) {
+ default:
+ /*printf("bad colourmaptype!\n");*/
+ return 0;
+ case 0:
+ case 1:
+ break;
+ }
+
+ return 1;
+}
+
+
/*
=item tga_header_pack(header, headbuf)
s->len = (s->hdr &~(1<<7))+1;
s->state = (s->hdr & (1<<7)) ? Rle : Raw;
+ {
+/*
+ static cnt = 0;
+ printf("%04d %s: %d\n", cnt++, s->state==Rle?"RLE":"RAW", s->len);
+ */
+ }
if (s->state == Rle && s->ig->readcb(s->ig, s->cval, s->bytepp) != s->bytepp) return 0;
break;
case Rle:
- ml = min(s->len, pixels-cp);
+ ml = i_min(s->len, pixels-cp);
for(k=0; k<ml; k++) for(j=0; j<s->bytepp; j++)
buf[(cp+k)*s->bytepp+j] = s->cval[j];
- // memset(buf+cp, s->cidx, ml);
cp += ml;
s->len -= ml;
break;
case Raw:
- ml = min(s->len, pixels-cp);
+ ml = i_min(s->len, pixels-cp);
if (s->ig->readcb(s->ig, buf+cp*s->bytepp, ml*s->bytepp) != ml*s->bytepp) return 0;
cp += ml;
s->len -= ml;
static
int
tga_dest_write(tga_dest *s, unsigned char *buf, size_t pixels) {
- int cp = 0, j, k;
+ int cp = 0;
if (!s->compressed) {
if (s->ig->writecb(s->ig, buf, pixels*s->bytepp) != pixels*s->bytepp) return 0;
int nxtrip = find_repeat(buf+cp*s->bytepp, pixels-cp, s->bytepp);
tlen = (nxtrip == -1) ? pixels-cp : nxtrip;
while(tlen) {
- int clen = (tlen>128) ? 128 : tlen;
+ unsigned char clen = (tlen>128) ? 128 : tlen;
clen--;
if (s->ig->writecb(s->ig, &clen, 1) != 1) return 0;
clen++;
}
if (cp >= pixels) break;
tlen = find_span(buf+cp*s->bytepp, pixels-cp, s->bytepp);
+ if (tlen <3) continue;
while (tlen) {
- int clen = (tlen>128) ? 128 : tlen;
+ unsigned char clen = (tlen>128) ? 128 : tlen;
clen = (clen - 1) | 0x80;
if (s->ig->writecb(s->ig, &clen, 1) != 1) return 0;
clen = (clen & ~0x80) + 1;
i_img *
i_readtga_wiol(io_glue *ig, int length) {
- i_img* img;
- int x, y, i;
+ i_img* img = NULL;
+ int x, y;
int width, height, channels;
int mapped;
- char *idstring;
+ char *idstring = NULL;
tga_source src;
tga_header header;
unsigned char headbuf[18];
unsigned char *databuf;
- unsigned char *reorderbuf;
i_color *linebuf = NULL;
i_clear_error();
i_push_error(errno, "short read on targa idstring");
return NULL;
}
- myfree(idstring); /* Move this later, once this is stored in a tag */
}
width = header.width;
height = header.height;
+
/* Set tags here */
switch (header.datatypecode) {
case 0: /* No data in image */
i_push_error(0, "Targa image contains no image data");
+ if (idstring) myfree(idstring);
return NULL;
break;
case 1: /* Uncompressed, color-mapped images */
case 11: /* Compressed, grayscale images */
if (header.bitsperpixel != 8) {
i_push_error(0, "Targa: mapped/grayscale image's bpp is not 8, unsupported.");
+ if (idstring) myfree(idstring);
return NULL;
}
src.bytepp = 1;
if ((src.bytepp = bpp_to_bytes(header.bitsperpixel)))
break;
i_push_error(0, "Targa: direct color image's bpp is not 15/16/24/32 - unsupported.");
+ if (idstring) myfree(idstring);
return NULL;
break;
case 32: /* Compressed color-mapped, Huffman, Delta and runlength */
case 33: /* Compressed color-mapped, Huffman, Delta and runlength */
i_push_error(0, "Unsupported Targa (Huffman/delta/rle/quadtree) subformat is not supported");
+ if (idstring) myfree(idstring);
return NULL;
break;
default: /* All others which we don't know which might be */
i_push_error(0, "Unknown targa format");
+ if (idstring) myfree(idstring);
return NULL;
break;
}
mapped = 1;
switch (header.datatypecode) {
- int tbpp;
case 2: /* Uncompressed, rgb images */
case 10: /* Compressed, rgb images */
mapped = 0;
header.colourmapdepth :
header.bitsperpixel))) break;
i_push_error(0, "Targa Image has none of 15/16/24/32 pixel layout");
+ if (idstring) myfree(idstring);
return NULL;
break;
case 3: /* Uncompressed, grayscale images */
channels = 1;
break;
}
+
+ if (!i_int_check_image_file_limits(width, height, channels,
+ sizeof(i_sample_t))) {
+ mm_log((1, "i_readtga_wiol: image size exceeds limits\n"));
+ return NULL;
+ }
img = mapped ?
i_img_pal_new(width, height, channels, 256) :
i_img_empty_ch(NULL, width, height, channels);
+
+ if (!img) {
+ if (idstring)
+ myfree(idstring);
+ return NULL;
+ }
+ if (idstring) {
+ i_tags_add(&img->tags, "tga_idstring", 0, idstring, header.idlength, 0);
+ myfree(idstring);
+ }
+
if (mapped &&
!tga_palette_read(ig,
img,
header.colourmaplength)
) {
i_push_error(0, "Targa Image has none of 15/16/24/32 pixel layout");
+ if (idstring) myfree(idstring);
+ if (img) i_img_destroy(img);
return NULL;
}
if (!tga_source_read(&src, databuf, width)) {
i_push_error(errno, "read for targa data failed");
myfree(databuf);
+ if (img) i_img_destroy(img);
return NULL;
}
if (mapped && header.colourmaporigin) for(x=0; x<width; x++) databuf[x] -= header.colourmaporigin;
}
myfree(databuf);
if (linebuf) myfree(linebuf);
+
+ i_tags_add(&img->tags, "i_format", 0, "tga", -1, 0);
+ i_tags_addn(&img->tags, "tga_bitspp", 0, mapped?header.colourmapdepth:header.bitsperpixel);
+ if (src.compressed) i_tags_addn(&img->tags, "compressed", 0, 1);
return img;
}
undef_int
i_writetga_wiol(i_img *img, io_glue *ig, int wierdpack, int compress, char *idstring, size_t idlen) {
- static int rgb_chan[] = { 2, 1, 0, 3 };
tga_header header;
tga_dest dest;
unsigned char headbuf[18];
- // unsigned char *data;
unsigned int bitspp;
int mapped;
io_glue_commit_types(ig);
- header.idlength;
header.idlength = idlen;
header.colourmaptype = mapped ? 1 : 0;
header.datatypecode = mapped ? 1 : img->channels == 1 ? 3 : 2;
mm_log((1, "dest.bytepp = %d\n", dest.bytepp));
if (img->type == i_palette_type) {
- int i;
- int bytepp = bpp_to_bytes(bitspp);
if (!tga_palette_write(ig, img, bitspp, i_colorcount(img))) return 0;
if (!img->virtual && !dest.compressed) {
myfree(buf);
myfree(vals);
}
+
+ ig->closecb(ig);
+
return 1;
}
+
+/*
+=back
+
+=head1 AUTHOR
+
+Arnar M. Hrafnkelsson <addi@umich.edu>
+
+=head1 SEE ALSO
+
+Imager(3)
+
+=cut
+*/