⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readtga.c

📁 zgv-5.6,一个Linux系统下的图片浏览器(VGA/SVGA)
💻 C
字号:
/* zgv 5.5 - GIF, JPEG and PBM/PGM/PPM viewer, for VGA PCs running Linux. * Copyright (C) 1993-2001 Russell Marks. See README for license details. * * readtga.c - loads TGA files (based on readpnm.c). * * only supports file types 1, 2, 9 and 10, since that's all I've * got documentation for. If you want support for the others, * write it yourself. ;-) */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include "zgv.h"#include "readtga.h"#include "readpnm.h"	/* for dithering routines */#include "rcfile.h"#include "rc_config.h"/* for aborted_file_tga_cleanup() */static unsigned char *work_bmap,*work_pal;static FILE *work_in;int tga_need_flip;/* prototypes *//* (none needed) *//* convert 16-bit at ptr to 24-bit. */static void fix16bit(unsigned char *ptr,int width){static unsigned char scaleup[32];static int first=1;unsigned char *src,*dst;if(first)  {  int f;    first=0;  for(f=0;f<32;f++)    scaleup[f]=(f*255)/31;  }/* does it right-to-left to avoid needing temporary buffer */dst=ptr+width*3;for(src=ptr+width*2;src>ptr;src-=2)  {  *--dst=scaleup[(src[-1]>>2)&31];  *--dst=scaleup[src[-2]>>5 | (src[-1]&3)<<3];  *--dst=scaleup[src[-2]&31];  }}int read_tga_file(char *filename,hffunc howfarfunc,unsigned char **bmap,                  unsigned char **pal,int *output_type,PICINFO *pp){FILE *in;struct tgahed hed;int c,w,h,bytepp,x,y,i,cmapstart,cmaplen;int rle_left=0,rle_pkt=0;unsigned char rle_byte[3],*rle_ptr=NULL;unsigned char *ptr;int filebytepp=1;*bmap=NULL;*pal=NULL;if((in=fopen(filename,"rb"))==NULL)  return(_PICERR_NOFILE);if(fread(&hed,sizeof(hed),1,in)!=1)  CLOSE_AND_RET(_PICERR_BADMAGIC);cmapstart=(hed.cmapstart_hi<<8)+hed.cmapstart_lo;cmaplen  =(hed.cmaplen_hi<<8)  +hed.cmaplen_lo;switch(hed.type)  {  case 1:  case 9:    bytepp=1;    break;  case 2:  case 10:    bytepp=3;    filebytepp=hed.bpp/8;    if(filebytepp<1 || filebytepp>3)      filebytepp=3;    break;  default:    CLOSE_AND_RET(_PICERR_BADMAGIC);  }/* skip any id field */for(i=0;i<hed.idfieldlen;i++) fgetc(in);if((*pal=calloc(768,1))==NULL)  CLOSE_AND_RET(_PICERR_NOMEM);else  {  int r,g,b;  ptr=*pal;  /* only actually used if using 8-bit display, but defined always */  for(r=0;r<8;r++)    for(g=0;g<8;g++)	/* colours are 3:3:2 */      for(b=0;b<4;b++)        {        *ptr=r*255/7; ptr[256]=g*255/7; ptr[512]=b*255/3;        ptr++;        }  }/* read colour map if there is one - note we actually skip it entirely * if some hoser put a colourmap on a 24-bit file (which is possible * with TGA apparently; duh, I'll have the 16 meg palette please Bob). */if(hed.hascmap)  {  int bytecmapd;  unsigned char tmp[4];    if(cmapstart+cmaplen>256)    CLOSE_AND_RET(_PICERR_CORRUPT);		/* just in case... */  if(hed.cmapdepth!=16 && hed.cmapdepth!=24 && hed.cmapdepth!=32)    CLOSE_AND_RET(_PICERR_CORRUPT);  bytecmapd=hed.cmapdepth/8;  if(hed.type==2 || hed.type==10)	/* supported RGB types */    {    /* skip colourmap */    for(i=0;i<cmaplen;i++) fread(tmp,bytecmapd,1,in);    }  else    {    /* read colourmap */    ptr=*pal;    for(i=0;i<cmaplen;i++)      {      fread(tmp,bytecmapd,1,in);      switch(hed.cmapdepth)        {        case 16:          c=((tmp[1]<<8)|tmp[0]);          ptr[    cmapstart+i]=(( c     &31)*255)/31;          ptr[256+cmapstart+i]=(((c>> 5)&31)*255)/31;          ptr[512+cmapstart+i]=(((c>>10)&31)*255)/31;        case 24: case 32:          ptr[    cmapstart+i]=tmp[2];          ptr[256+cmapstart+i]=tmp[1];          ptr[512+cmapstart+i]=tmp[0];        }      }    }  }w=(hed.width_hi<<8) +hed.width_lo;h=(hed.height_hi<<8)+hed.height_lo;if(w==0 || h==0)  CLOSE_AND_RET(_PICERR_CORRUPT);if(bytepp==3 && (*output_type==1 || cfg.jpeg24bit==0))	/* dither? */  {  bytepp=1;  if(ditherinit(w)==0)    CLOSE_AND_RET(_PICERR_NOMEM);  }/* we allocate two blank lines at the end. reason is the dithering * of PPM files to 8-bit works a line at a time, and we need * 3 times as much for each line, which works out only meaning * 3x as much for the last line. If you see what I mean. (!?) */if((*bmap=malloc(w*(h+2)*bytepp))==NULL)  CLOSE_AND_RET(_PICERR_NOMEM);ptr=*bmap;/* save stuff in case of abort */work_in=in; work_bmap=ptr; work_pal=*pal;tga_need_flip=(hed.desc&32)?0:1;/* read in the image * no errors are detected once we start reading. * now, of course, TGA files are stored backwards. rather than * try to cope with this, I *completely* ignore it until the whole * image is read in, then I flip the image. :-) */switch(hed.type)  {  case 1: case 2:    /* uncompressed */    for(y=0;y<h;y++)      {      fread(ptr,filebytepp,w,in);            if(filebytepp==2)        fix16bit(ptr,w);            /* dither if required */      if(hed.type==2 && bytepp==1)        ditherline(ptr,y,w);      ptr+=bytepp*w;      if(howfarfunc!=NULL) howfarfunc(y,h);      }    break;    case 9: case 10:    /* RLE compressed */    rle_left=0;    for(y=0;y<h;y++)      {      static unsigned char buf[128*3];            for(x=0;x<w;x++)        {        if(rle_left==0)          {          c=fgetc(in);          rle_pkt=(c&128)?1:0;          rle_left=(c&127)+1;          if(rle_pkt)            fread(rle_ptr=rle_byte,filebytepp,1,in);          else            fread(rle_ptr=buf     ,filebytepp,rle_left,in);          }                memcpy(ptr,rle_ptr,filebytepp);        if(!rle_pkt) rle_ptr+=filebytepp;        rle_left--;        ptr+=filebytepp;        }            if(filebytepp==2)        fix16bit(ptr-filebytepp*w,w);            /* dither if required */      if(hed.type==10 && bytepp==1)        {        ptr-=3*w;        ditherline(ptr,y,w);        ptr+=w;        }            if(howfarfunc!=NULL) howfarfunc(y,h);      }    break;  }pp->width=w;pp->height=h;pp->numcols=256;*output_type=bytepp;if((hed.type==2 || hed.type==10) && bytepp==1)  ditherfinish();  fclose(in);/* the image is actually flipped in vgadisp.c */return(_PIC_OK);  }void aborted_file_tga_cleanup(){free(work_bmap);free(work_pal);fclose(work_in);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -