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

📄 vgadisp.c

📁 zgv-5.6,一个Linux系统下的图片浏览器(VGA/SVGA)
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* hopefully the following is fairly quick as fewer ifs... ? */  if(virtual && scaling==1)		/* 320x400 or 360x480 */    {    if((realline=calloc(1,scrnwide))==NULL) return;    for(y=0;(y<sheight-py)&&(y<scrnhigh);y++)      {      for(x=0;x<xdim;x++)        *(realline+(x>>1))=getvpix(px,py,x,y);      vga_drawscansegment(realline,x_add,y+y_add,xdim>>1);      }    free(realline);    }  else if(scaling>1)    {    /* Better grab your Joo Janta 200 Super-Chromatic Peril Sensitive     * Sunglasses (both pairs) for this next bit...     */    int cdown=-1,i,pxx,pyy,pyym;    int a1,a2,a3,a4,in_rg,in_dn,in_dr;    int wp=width*pixelsize,sci=scaling*inextpix;    int scaleincr=0,subpix_xpos,subpix_ypos,sxmulsiz,symulsiz,simulsiz=0;    int sisize=0,sis2=0;    unsigned char *ptr1,*ptr2,*ptr3,*ptr4;    unsigned char *src,*dst;        if((realline=calloc(pixelsize,scrnwide))==NULL) return;        if(interp)      {      sisize=0;      while(sisize<256) sisize+=scaling;      scaleincr=sisize/scaling;      simulsiz=scaleincr*sisize;      sis2=sisize*sisize;      }        for(y=0,pyy=py;(y<sheight-py)&&(y<scrnhigh);y++,pyy++)      {      /* this is horribly slow... :-( */      if(cdown<=0 || interp)        {        src=theimage+pixelsize*(pyy/scaling)*width;        dst=realline;        if(pixelsize==1)          if(virtual)            for(x=0;(x<swidth-px)&&(x<scrnwide);x+=2)              *dst++=*(src+(px+x)/scaling);          else            for(x=0;(x<swidth-px)&&(x<scrnwide);x++)              *dst++=*(src+(px+x)/scaling);        else if(interp==0)          /* normal */          for(x=0;(x<swidth-px)&&(x<scrnwide);x++)            {            ptr=src+((px+x)/scaling)*pixelsize;            *dst++=*ptr++; *dst++=*ptr++; *dst++=*ptr;            }        else          {          /* interpolated */                    /* This has been hacked into unreadability in an attempt to get it           * as fast as possible.           * It's still really slow. :-(           */          in_rg=inextpix*3;          in_dn=inextpix*wp;          in_dr=in_dn+in_rg;          pyym=pyy%scaling;          subpix_ypos=(pyy%scaling)*scaleincr;          subpix_xpos=(px%scaling)*scaleincr;  /* yes px not pxx */                    ptr1=ptr3=src+(px/scaling)*3;          ptr2=ptr4=ptr1+in_rg;          if(pyy<sheight-sci)            {            ptr3=ptr1+in_dn;            ptr4=ptr1+in_dr;            }                    symulsiz=sisize*subpix_ypos;          sxmulsiz=sisize*subpix_xpos;                    for(x=0,pxx=px;x<swidth-px && x<scrnwide;x++,pxx++)            {            a3=symulsiz-(a4=subpix_xpos*subpix_ypos);            a2=sxmulsiz-a4;            a1=sis2-sxmulsiz-symulsiz+a4;            for(i=0;i<3;i++)              *dst++=(ptr1[i]*a1+ptr2[i]*a2+                      ptr3[i]*a3+ptr4[i]*a4)/sis2;                          subpix_xpos+=scaleincr;            sxmulsiz+=simulsiz;            if(subpix_xpos>=sisize)              {              subpix_xpos=sxmulsiz=0;              ptr1+=3; ptr2+=3; ptr3+=3; ptr4+=3;              }            if(pxx>=swidth-sci)              {              ptr2-=3;              ptr4-=3;              }            }          }                      cdown=(cdown==-1)?(scaling-(py%scaling)):scaling;        }            cdown--;            if(scrnpixelsize==3 && !doing_hicol_bc)        gl_putbox(x_add,y+y_add,linelen,1,realline);      else        if(virtual)          vga_drawscansegment(realline,x_add,y+y_add,linelen>>1);        else          eventuallydrawscansegment(realline,x_add,y+y_add,linelen*pixelsize);      }    free(realline);    }  else		/* if not scaled and not zoomed... */    {    switch(scrnpixelsize)      {      case 3:        if(!doing_hicol_bc)          {          gl_putboxpart(x_add,y_add,(scrnwide<width)?scrnwide:width,	  	(scrnhigh<height)?scrnhigh:height,width,height,theimage,px,py);          break;          }        /* otherwise, FALLS THROUGH */            default:        /* for 320x200 (I think), 320x240, 320x400, 360x480 we need the         * length to be a multiple of 8. :-( We allocate an image-width         * line (blanked), and display via that.         * (320x400/360x480 were dealt with earlier though; can only         * be 320x200/320x240 if it gets here.)         *         * This isn't needed for svgalib >=1.3.1, but I'm leaving it in         * for `if it ain't broke don't fix it' reasons. :-)         */        if(curvgamode==G320x200x256 || curvgamode==G320x240x256)          {          static unsigned char hack[320];                    memset(hack,0,320);          for(y=0;(y<height-py)&&(y<scrnhigh);y++)            {            /* assume pixelsize==1, because it must be */            memcpy(hack+x_add,theimage+((py+y)*width+px),xdim);            vga_drawscansegment(hack,0,y+y_add,scrnwide);            }          }        else          for(y=0;(y<height-py)&&(y<scrnhigh);y++)            eventuallydrawscansegment(theimage+pixelsize*((py+y)*width+px),            	x_add,y+y_add,xdim*pixelsize);        break;      }    }  }}#define MODE_WIDTH_BUF_SIZE	16384/* this variant should never be called with scrnpixelsize==3. */void eventuallydrawscansegment_without_bc(byte *ptr,int x,int y,int len){static unsigned short buf[MODE_WIDTH_BUF_SIZE];switch(scrnpixelsize)  {  case 4:	/* 32-bit */    {    unsigned long *bufref=(unsigned long *)buf;    unsigned char *ptrend=ptr+len;    int i=0;        for(;ptr<ptrend;ptr+=3,i++)      *bufref++=GET32BITCOLOUR(ptr[2],ptr[1],*ptr);    gl_putbox(x,y,i,1,buf);    }    break;      case 2:	/* 15/16-bit */    {    unsigned short *bufref=buf;    unsigned char *ptrend=ptr+len;        if(scrncols==32768)      for(;ptr<ptrend;ptr+=3)        *bufref++=GET15BITCOLOUR(ptr[2],ptr[1],*ptr);    else      for(;ptr<ptrend;ptr+=3)        *bufref++=GET16BITCOLOUR(ptr[2],ptr[1],*ptr);        gl_putbox(x,y,bufref-buf,1,buf);    }    break;      default:	/* 8-bit */    if(curvgamode==G640x480x16)      dither16scansegment(ptr,x,y,len);    else      vga_drawscansegment(ptr,x,y,len);  }}void eventuallydrawscansegment_with_bc(byte *ptr,int x,int y,int len){static unsigned short buf[MODE_WIDTH_BUF_SIZE];unsigned char *ptrend=ptr+len;/* if we get here, scrnpixelsize must be 2, 3, or 4. */switch(scrnpixelsize)  {  case 4:	/* 32-bit */    {    unsigned long *bufref=(unsigned long *)buf;    unsigned char *ptrend=ptr+len;    int i=0;        for(;ptr<ptrend;ptr+=3,i++)      *bufref++=GET32BITCOLOUR(palt[ptr[2]],palt[ptr[1]],palt[*ptr]);    gl_putbox(x,y,i,1,buf);    }    break;    case 3:	/* 24-bit */    {    unsigned char *bufref=(unsigned char *)buf;	/* no kludges here, senor */        while(ptr<ptrend)      *bufref++=palt[*ptr++];        gl_putbox(x,y,(bufref-(unsigned char *)buf)/3,1,buf);    break;    }    case 2:	/* 15/16-bit */    {    unsigned short *bufref=buf;        if(scrncols==32768)      for(;ptr<ptrend;ptr+=3)        *bufref++=GET15BITCOLOUR(palt[ptr[2]],palt[ptr[1]],palt[*ptr]);    else      for(;ptr<ptrend;ptr+=3)        *bufref++=GET16BITCOLOUR(palt[ptr[2]],palt[ptr[1]],palt[*ptr]);        gl_putbox(x,y,bufref-buf,1,buf);    break;    }    default:    fprintf(stderr,"not high-colour in ..._with_bc, can't happen!\n");    exit(1);  }}/* only called for 640x480x4-bit */void dither16scansegment(unsigned char *ptr,int x,int y,int len){static unsigned char scanline[640];unsigned char *lptr=scanline;int f;if(!cfg.viewer16col)  {  /* greyscale, but dithered between the scales;   * dithering slows it down more than a direct mapping would,   * but it just looks too nasty without it.   */  static unsigned char ditherdata[4]=    {    1,4,    3,2    };  unsigned char c,*dithptr=ditherdata+(y&1)*2+(x&1);  int xm=2-(x&1);    for(f=0;f<len;f++)    {    if((c=dither16_greylookup[ptr[f]])>=60)      c=60;	/* saves needing a range check after :-) */        *lptr++=((c>>2)+((c&3)>=*dithptr++));    if(!(--xm))      dithptr-=(xm=2);    }  }else  {  /* colour */  if(cfg.fastdither16col)    {    /* ordered dither */    static unsigned char ditherdata[48]=      {      /* red */       1*4-2,13*4-2, 4*4-2,16*4-2,       9*4-2, 5*4-2,12*4-2, 8*4-2,       3*4-2,15*4-2, 2*4-2,14*4-2,       7*4-2,10*4-2, 6*4-2,11*4-2,             /* green - mirrored */      16*4-2, 4*4-2,13*4-2, 1*4-2,       8*4-2,12*4-2, 5*4-2, 9*4-2,      14*4-2, 2*4-2,15*4-2, 3*4-2,      11*4-2, 6*4-2,10*4-2, 7*4-2,            /* blue - flipped */       7*4-2,10*4-2, 6*4-2,11*4-2,       3*4-2,15*4-2, 2*4-2,14*4-2,       9*4-2, 5*4-2,12*4-2, 8*4-2,       1*4-2,13*4-2, 4*4-2,16*4-2      };    unsigned char *dithptr=ditherdata+(y&3)*4+(x&3);    unsigned char *palptr;    int xm=4-(x&3);      for(f=0;f<len;f++)      {      palptr=dither16_rgb+ptr[f]*3;      *lptr++=(((*palptr>=*dithptr)*4)|               ((palptr[1]>=dithptr[16])*2)|               (palptr[2]>=dithptr[32]));      dithptr++;      if(!(--xm))        dithptr-=(xm=4);      }    }  else    {    /* error-diffused dither, based on the one in readpnm.c */    static int evenerr[(640+10)*3],odderr[(640+10)*3];  /* 640x480-only */    static int oldline=(1<<30);    unsigned char *theline=ptr;    int width=len;    int xx,lx;    int c0,c1,c2,times2;    int terr0,terr1,terr2,actual0,actual1,actual2;    int start,addon,r,g,b,c;    int *thiserr;    int *nexterr;    /* we assume going backwards = new set of lines being drawn */    if(y<oldline)      {      memset(evenerr,0,sizeof(evenerr));      memset(odderr,0,sizeof(odderr));      }    oldline=y;      if((y&1)==0)      {start=0; addon=1;      thiserr=evenerr+3; nexterr=odderr+width*3;}    else      {start=width-1; addon=-1;      thiserr=odderr+3; nexterr=evenerr+width*3;}    nexterr[0]=nexterr[1]=nexterr[2]=0;    xx=start;    for(lx=0;lx<width;lx++)      {      c=theline[xx];      b=palb[c];      g=palg[c];      r=palr[c];      terr0=r+((thiserr[0]+8)>>4);      terr1=g+((thiserr[1]+8)>>4);      terr2=b+((thiserr[2]+8)>>4);            actual0=(terr0>=128)?255:0;      actual1=(terr1>=128)?255:0;      actual2=(terr2>=128)?255:0;      c=(((actual0&1)<<2)|((actual1&1)<<1)|(actual2&1));            c0=terr0-actual0;      c1=terr1-actual1;      c2=terr2-actual2;      times2=(c0<<1);      nexterr[-3] =c0; c0+=times2;      nexterr[ 3]+=c0; c0+=times2;      nexterr[ 0]+=c0; c0+=times2;      thiserr[ 3]+=c0;      times2=(c1<<1);      nexterr[-2] =c1; c1+=times2;      nexterr[ 4]+=c1; c1+=times2;      nexterr[ 1]+=c1; c1+=times2;      thiserr[ 4]+=c1;      times2=(c2<<1);      nexterr[-1] =c2; c2+=times2;      nexterr[ 5]+=c2; c2+=times2;      nexterr[ 2]+=c2; c2+=times2;      thiserr[ 5]+=c2;      scanline[xx]=c;      thiserr+=3;      nexterr-=3;      xx+=addon;      }    }  }vga_drawscansegment(scanline,x,y,len);}int getvpix(int px,int py,int x,int y){int p1,p2;if((vkludge)&&(pixelsize==1))  {  p1=*(theimage+(py+y)*width+px+x);  if(px+x+1>=width) return(p1);  p1*=3;  p2=*(theimage+(py+y)*width+px+x+1)*3;  return(closest((pal32_no_bc[p1  ]+pal32_no_bc[p2  ])>>1,                 (pal32_no_bc[p1+1]+pal32_no_bc[p2+1])>>1,                 (pal32_no_bc[p1+2]+pal32_no_bc[p2+2])>>1));  }else  return(*(theimage+pixelsize*((py+y)*width+px+x)));}/* this routine is nasty writ big, but about as quick as I can manage */void drawzoomedgif(){int a,b,x,yp,yw;long y,sw,sh,lastyp;int xoff,yoff;int x_add,y_add;	/* for centering */int pixwide,pixhigh;int bigimage;byte *rline,*sptr,*dptr;int tmp1,tmp2,tr,tg,tb,tn;if((rline=calloc(scrnwide*pixelsize,1))==NULL) return;/* try landscapey */sw=scrnwide; sh=(scrnwide*height)/width;if(sh>scrnhigh)  /* no, oh well portraity then */  sh=scrnhigh,sw=(scrnhigh*width)/height;/* so now our zoomed image will be sw x sh *//* fix centering if needed */x_add=y_add=0;if(cfg.centreflag)  {  if(sw<scrnwide)    x_add=((scrnwide-sw)>>1);    if(sh<scrnhigh)    y_add=((scrnhigh-sh)>>1);    if(virtual) x_add>>=1;  }bigimage=(width>sw)?1:0;   /* 1 if image has been reduced, 0 if made bigger */if(bigimage)  /* it's been reduced - easy, just make 'em fit in less space */  {  if(virtual) sw>>=1;  lastyp=-1;  if(!override_zoom_clear)	/* for animate_gif() */    vga_clear();  pixhigh=(int)(((float)height)/((float)sh)+0.5);  pixwide=(int)(((float)width)/((float)sw)+0.5);  pixhigh++;  pixwide++;  for(y=0;y<height;y+

⌨️ 快捷键说明

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