?? tga.c
字號:
fprintf(stderr,"write_tga: could not write TGA footer magic (fwrite: %s)\n",pstrerror(errno)); /* Ready */ file_wpop(); return 0;}static int RLE_decompress(FILE *f, void *buf, int bufsize, int pixelsize) { unsigned char pt; unsigned char *bufp; unsigned char temp[8]; /* MAXPIXELSIZE */ int bufi; int count; file_rpush(f); bufp = buf; for (bufi=0; bufi<bufsize; ) { pt = file_readb(); if (feof(f)) { fprintf(stderr,"RLE_decompress: after final packet only got %d of %d bytes\n",bufi,bufsize); file_rpop(); return -1; } count = (pt & 0x7f)+1; if (bufi+count*pixelsize>bufsize) { fprintf(stderr,"RLE_decompress: buffer too short for next packet (need %d bytes, have %d)\n",bufi+count*pixelsize,bufsize); file_rpop(); return -1; } if ((pt & 0x80) == 0) { /* RAW PACKET */ if (fread(bufp,pixelsize,count,f)<(unsigned)count) { if (feof(f)) fprintf(stderr,"RLE_decompress: short RAW packet (expected %d bytes) (EOF)\n",pixelsize*count); else fprintf(stderr,"RLE_decompress: short RAW packet (expected %d bytes) (fread: %s)\n",pixelsize*count,pstrerror(errno));#if 0 file_rpop(); return -1;#endif } bufp += count*pixelsize; bufi += count*pixelsize; } else { /* RLE PACKET */ if (fread(temp,pixelsize,1,f) < 1) { if (feof(f)) fprintf(stderr,"RLE_decompress: short RLE packet (expected %d bytes) (EOF)\n",pixelsize); else fprintf(stderr,"RLE_decompress: short RLE packet (expected %d bytes) (fread: %s)\n",pixelsize,pstrerror(errno));#if 0 file_rpop(); return -1;#endif } if (count<2) { fprintf(stderr,"RLE_decompress: suspicious RLE repetition count %d\n",count); } for (;count > 0; count--) { memcpy(bufp,temp,pixelsize); bufp += pixelsize; bufi += pixelsize; } } } file_rpop(); return 0;}static void RLE_write_pkt(FILE *f, t_tgapkttype pkttype, int len, void *data, int pixelsize) { unsigned char count; if (len<1 || len>128) { fprintf(stderr,"RLE_write_pkt: packet has bad length (%d bytes)\n",len); return; } if (pkttype==RLE) { if (len<2) { fprintf(stderr,"RLE_write_pkt: RLE packet has bad length (%d bytes)\n",len); return; } count = (unsigned char)(0x80 | (len-1)); if (fwrite(&count, 1, 1, f)<1) fprintf(stderr,"RLE_write_pkt: could not write RLE pixel count (fwrite: %s)\n",pstrerror(errno)); if (fwrite(data, pixelsize, 1, f)<1) fprintf(stderr,"RLE_write_pkt: could not write RLE pixel value (fwrite: %s)\n",pstrerror(errno)); } else { count = (unsigned char) (len-1); if (fwrite(&count, 1, 1, f)<1) fprintf(stderr,"RLE_write_pkt: could not write RAW pixel count (fwrite: %s)\n",pstrerror(errno)); if (fwrite(data,pixelsize,len,f)<(unsigned)len) fprintf(stderr,"RLE_write_pkt: could not write %d RAW pixels (fwrite: %s)\n",len,pstrerror(errno)); }}static int RLE_compress(FILE *f, t_tgaimg const *img) { int pixelsize; unsigned char const *datap; unsigned char *pktdata; unsigned int pktlen; t_tgapkttype pkttype; unsigned char *pktdatap; unsigned int actual=0,perceived=0; int i; pkttype = RAW; pktdatap = NULL; if (img == NULL) return -1; if (img->data == NULL) return -1; pixelsize = getpixelsize(img); if (pixelsize == 0) return -1; datap = img->data; pktdata = malloc(img->width*img->height*pixelsize); pktlen = 0; for (i=0; i<img->width*img->height; ) { if (pktlen == 0) { pktdatap = pktdata; memcpy(pktdatap,datap,pixelsize); pktlen++; i++; pktdatap += pixelsize; datap += pixelsize; pkttype = RAW; continue; } if (pktlen == 1) { if (memcmp(datap-pixelsize,datap,pixelsize)==0) { pkttype = RLE; } } if (pkttype == RLE) { if (memcmp(datap-pixelsize,datap,pixelsize)!=0 || pktlen>=128) { RLE_write_pkt(f,pkttype,pktlen,pktdata,pixelsize); actual += 1+pixelsize; perceived += pixelsize*pktlen; pktlen = 0; } else { pktlen++; i++; datap += pixelsize; } } else { if (memcmp(datap-pixelsize,datap,pixelsize)==0 || pktlen>=129) { datap -= pixelsize; /* push back last pixel */ i--; if (i<0) fprintf(stderr,"BUG!\n"); pktlen--; RLE_write_pkt(f,pkttype,pktlen,pktdata,pixelsize); actual += 1+pixelsize*pktlen; perceived += pixelsize*pktlen; pktlen = 0; } else { memcpy(pktdatap,datap,pixelsize); pktlen++; i++; pktdatap += pixelsize; datap += pixelsize; } } } if (pktlen) { RLE_write_pkt(f,pkttype,pktlen,pktdata,pixelsize); if (pkttype==RLE) { actual += 1+pixelsize; perceived += pixelsize*pktlen; } else { actual += 1+pixelsize*pktlen; perceived += pixelsize*pktlen; } pktlen = 0; } fprintf(stderr,"RLE_compress: wrote %u bytes (%u uncompressed)\n",actual,perceived); return 0;}extern void destroy_img(t_tgaimg * img) { if (img == NULL) return; if (img->data) free(img->data); free(img);}extern void print_tga_info(t_tgaimg const * img, FILE * fp) { unsigned int interleave; unsigned int attrbits; char const * typestr; char const * cmapstr; char const * horzstr; char const * vertstr; char const * intlstr; if (!img || !fp) return; interleave = ((img->desc&tgadesc_interleave1)!=0)*2+((img->desc&tgadesc_interleave2)!=0); attrbits = img->desc&(tgadesc_attrbits0|tgadesc_attrbits1|tgadesc_attrbits2|tgadesc_attrbits3); switch (img->imgtype) { case tgaimgtype_empty: typestr = "No Image Data Included"; break; case tgaimgtype_uncompressed_mapped: typestr = "Uncompressed, Color-mapped Image"; break; case tgaimgtype_uncompressed_truecolor: typestr = "Uncompressed, True-color Image"; break; case tgaimgtype_uncompressed_monochrome: typestr = "Uncompressed, Black-and-white image"; break; case tgaimgtype_rlecompressed_mapped: typestr = "Run-length encoded, Color-mapped Image"; break; case tgaimgtype_rlecompressed_truecolor: typestr = "Run-length encoded, True-color Image"; break; case tgaimgtype_rlecompressed_monochrome: typestr = "Run-length encoded, Black-and-white image"; break; case tgaimgtype_huffman_mapped: typestr = "Huffman encoded, Color-mapped image"; break; case tgaimgtype_huffman_4pass_mapped: typestr = "Four-pass Huffman encoded, Color-mapped image"; break; default: typestr = "unknown"; } switch (img->cmaptype) { case tgacmap_none: cmapstr = "None"; break; case tgacmap_included: cmapstr = "Included"; break; default: cmapstr = "Unknown"; } if ((img->desc&tgadesc_horz)==0) { horzstr = "left"; } else { horzstr = "right"; } if ((img->desc&tgadesc_vert)==0) { vertstr = "bottom"; } else { vertstr = "top"; } switch (interleave) { case 0: intlstr = "none"; break; case 2: intlstr = "two way"; break; case 3: intlstr = "four way"; break; case 4: default: intlstr = "unknown"; break; } fprintf(fp,"TGAHeader: IDLength=%u ColorMapType=%u(%s)\n",img->idlen,img->cmaptype,cmapstr); fprintf(fp,"TGAHeader: ImageType=%u(%s)\n",img->imgtype,typestr); fprintf(fp,"TGAHeader: ColorMap: FirstEntryIndex=%u ColorMapLength=%u\n",img->cmapfirst,img->cmaplen); fprintf(fp,"TGAHeader: ColorMap: ColorMapEntrySize=%ubits\n",img->cmapes); fprintf(fp,"TGAHeader: X-origin=%u Y-origin=%u Width=%u(0x%x) Height=%u(0x%x)\n",img->xorigin,img->yorigin,img->width,img->width,img->height,img->height); fprintf(fp,"TGAHeader: PixelDepth=%ubits ImageDescriptor=0x%02x(%u attribute bits, origin is %s %s, interleave=%s)\n",img->bpp,img->desc,attrbits,vertstr,horzstr,intlstr);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -