"Fossies" - the Fresh Open Source Software Archive

Member "xzgv-0.9.2/src/resizepic.c" (3 Sep 2017, 4524 Bytes) of package /linux/misc/old/xzgv-0.9.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "resizepic.c" see the Fossies "Dox" file reference documentation.

    1 /* xzgv v0.2 - picture viewer for X, with file selector.
    2  * Copyright (C) 1999 Russell Marks. See main.c for license details.
    3  *
    4  * resizepic.c - resize pic with smoothing (for thumbnails).
    5  */
    6 
    7 #include <stdio.h>
    8 #include <string.h>
    9 #include <stdlib.h>
   10 #include <string.h>
   11 
   12 #include "resizepic.h"
   13 
   14 
   15 #define TN_CRUNCH_WIDTH     320
   16 #define TN_CRUNCH_HEIGHT    240
   17 
   18 
   19 
   20 /* used to resize (without smoothing) a picture loaded for
   21  * thumbnail generation into a (hopefully) smaller image,
   22  * which should then be reduced more nicely for the thumbnail.
   23  */
   24 unsigned char *nasty_resizepic(unsigned char *theimage,
   25                                int width,int height,int *sw_ask,int *sh_ask)
   26 {
   27 int x,y,yp,yw,sw,sh,lastyp,scrnwide,scrnhigh;
   28 unsigned char *rline,*outimage;
   29 
   30 scrnwide=*sw_ask;
   31 scrnhigh=*sh_ask;
   32 
   33 /* try landscapey */
   34 sw=scrnwide; sh=(scrnwide*height)/width;
   35 if(sh>scrnhigh)
   36   /* no, oh well portraity then */
   37   sh=scrnhigh,sw=(scrnhigh*width)/height;
   38 
   39 /* fix things for very thin images */
   40 if(sh==0) sh++;
   41 if(sw==0) sw++;
   42 
   43 *sw_ask=sw; *sh_ask=sh;
   44 
   45 /* so now our zoomed image will be sw x sh */
   46 
   47 if(width<=sw) return(NULL); /* abort if it's not smaller */
   48 
   49 /* extra line added to avoid segfaults from obiwan errors in dest
   50  * of memcpy() below. (I don't such errors are actually possible,
   51  * but it can't hurt anyway.)
   52  */
   53 if((outimage=malloc(sw*(sh+1)*3))==NULL)
   54   return(NULL);
   55 
   56 lastyp=-1;
   57 for(y=0;y<height;y++)
   58   {
   59   yp=(y*sh)/height;
   60   rline=outimage+yp*sw*3;
   61   if(yp!=lastyp)
   62     {
   63     yw=y*width;
   64     for(x=0;x<width;x++,yw++)
   65       memcpy(rline+(x*sw)/width*3,theimage+yw*3,3);
   66     lastyp=yp;
   67     }
   68   }
   69 
   70 return(outimage);
   71 }
   72 
   73 
   74 
   75 /* resamples from 'theimage' to a new malloc'ed area, a pointer to which is
   76  * the return value. 
   77  * width x height   - size of source image
   78  * sw_ask x sh_ask  - requested size of dest. image
   79  * input and output image both 24-bit.
   80  * new width x height in put back in sw_ask and sh_ask
   81  */
   82 unsigned char *resizepic(unsigned char *theimage,
   83                          int width,int height,int *sw_ask,int *sh_ask,
   84                          int allow_crunch)
   85 {
   86 int a,b,x,y,yp,yw,sw,sh,lastyp;
   87 int c,pixwide,pixhigh;
   88 int scrnwide,scrnhigh;
   89 unsigned char *rline;
   90 unsigned char *crunched=NULL;
   91 int tmp2,tr,tg,tb,tn;
   92 int xypos;
   93 
   94 /* first, see if it would benefit from being reduced without
   95  * smoothing (which is faster) before the `nice' resizing.
   96  */
   97 if(allow_crunch && (width>TN_CRUNCH_WIDTH || height>TN_CRUNCH_HEIGHT))
   98   {
   99   int our_sw_ask=TN_CRUNCH_WIDTH,our_sh_ask=TN_CRUNCH_HEIGHT;
  100   
  101   crunched=nasty_resizepic(theimage,width,height,&our_sw_ask,&our_sh_ask);
  102   
  103   /* if it worked, replace orig w/h with crunched pic's one, and
  104    * set theimage to point to it.
  105    */
  106   if(crunched)
  107     {
  108     width=our_sw_ask;
  109     height=our_sh_ask;
  110     theimage=crunched;
  111     }
  112   }
  113 
  114 scrnwide=*sw_ask;
  115 scrnhigh=*sh_ask;
  116 
  117 if((rline=calloc(scrnwide*scrnhigh*3,1))==NULL) return(0);
  118 
  119 /* try landscapey */
  120 sw=scrnwide; sh=(int)((scrnwide*((long)height))/((long)width));
  121 if(sh>scrnhigh)
  122   /* no, oh well portraity then */
  123   { sh=scrnhigh; sw=(int)((scrnhigh*((long)width))/((long)height)); }
  124 
  125 /* fix things for very thin images */
  126 if(sh==0) sh++;
  127 if(sw==0) sw++;
  128 
  129 *sw_ask=sw; *sh_ask=sh;
  130 
  131 /* so now our zoomed image will be sw x sh */
  132 if(width>sw || height>sh)
  133   /* it's been reduced - easy, just make 'em fit in less space */
  134   {
  135   lastyp=-1;
  136   pixhigh=(int)(((float)height)/((float)sh)+0.5);
  137   pixwide=(int)(((float)width)/((float)sw)+0.5);
  138   pixhigh++;
  139   pixwide++;
  140   for(y=0;y<height;y++)
  141     {
  142     yp=(y*sh)/height;
  143     if(yp!=lastyp)
  144       {
  145       yw=y*width;
  146       /* we try to resample it a bit */
  147       for(x=0;x<width;x++,yw++)
  148         {
  149         tr=tg=tb=tn=0;
  150         for(b=0;(b<pixhigh)&&(y+b<height);b++)
  151           for(a=0;(a<pixwide)&&(x+a<width);a++)
  152             {
  153             tmp2=(yw+a+b*width)*3;
  154             tr+=theimage[tmp2  ];
  155             tg+=theimage[tmp2+1];
  156             tb+=theimage[tmp2+2];
  157             tn++;
  158             }
  159         tr/=tn; tg/=tn; tb/=tn;
  160         xypos=3*(((x*sw)/width)+yp*scrnwide);
  161         rline[xypos]=tr;
  162         rline[xypos+1]=tg;
  163         rline[xypos+2]=tb;
  164         }
  165       lastyp=yp;
  166       }
  167     }
  168   }
  169 else
  170   /* we just leave it the same size */
  171   {
  172   *sw_ask=width; *sh_ask=height;
  173   for(y=0;y<height;y++)
  174     for(x=0;x<width;x++)
  175       {
  176       c=(y*width+x)*3;
  177       rline[3*(y*scrnwide+x)  ]=theimage[c  ];
  178       rline[3*(y*scrnwide+x)+1]=theimage[c+1];
  179       rline[3*(y*scrnwide+x)+2]=theimage[c+2];
  180       }
  181   }
  182 
  183 if(crunched) free(crunched);
  184   
  185 return(rline);
  186 }