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

📄 xvsmooth.c

📁 音视频编解码的H.263协议-C语言编写
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * xvsmooth.c - smoothing/color dither routines for XV * *  Contains: *            byte *SmoothResize(src8, swide, shigh, dwide, dhigh, *                               rmap, gmap, bmap, rdmap, gdmap, bdmap, maplen) *            byte *Smooth24(pic824, is24, swide, shigh, dwide, dhigh,  *                               rmap, gmap, bmap) *            byte *DoColorDither(pic24, pic8, w, h, rmap,gmap,bmap,  *                                rdisp, gdisp, bdisp, maplen) *            byte *Do332ColorDither(pic24, pic8, w, h, rmap,gmap,bmap,  *                                rdisp, gdisp, bdisp, maplen) */#include "copyright.h"#include "xv.h"static int smoothX  PARM((byte *, byte *, int, int, int, int, int,			  byte *, byte *, byte *));static int smoothY  PARM((byte *, byte *, int, int, int, int, int, 			  byte *, byte *, byte *));static int smoothXY PARM((byte *, byte *, int, int, int, int, int,			  byte *, byte *, byte *));/***************************************************/byte *SmoothResize(srcpic8, swide, shigh, dwide, dhigh, 		   rmap, gmap, bmap, rdmap, gdmap, bdmap, maplen)     byte *srcpic8, *rmap, *gmap, *bmap, *rdmap, *gdmap, *bdmap;     int   swide, shigh, dwide, dhigh, maplen;{  /* generic interface to Smooth and ColorDither code.       given an 8-bit-per, swide * shigh image with colormap rmap,gmap,bmap,      will generate a new 8-bit-per, dwide * dhigh image, which is dithered      using colors found in rdmap, gdmap, bdmap arrays */  /* returns ptr to a dwide*dhigh array of bytes, or NULL on failure */  byte *pic24, *pic8;  pic24 = Smooth24(srcpic8, 0, swide, shigh, dwide, dhigh, rmap, gmap, bmap);  if (pic24) {    pic8 = DoColorDither(pic24, NULL, dwide, dhigh, rmap, gmap, bmap,			 rdmap, gdmap, bdmap, maplen);    free(pic24);    return pic8;  }  return (byte *) NULL;}    /***************************************************/byte *Smooth24(pic824, is24, swide, shigh, dwide, dhigh, rmap, gmap, bmap)     byte *pic824, *rmap, *gmap, *bmap;     int   is24, swide, shigh, dwide, dhigh;{  /* does a SMOOTH resize from pic824 (which is either a swide*shigh, 8-bit     pic, with colormap rmap,gmap,bmap OR a swide*shigh, 24-bit image, based     on whether 'is24' is set) into a dwide * dhigh 24-bit image     returns a dwide*dhigh 24bit image, or NULL on failure (malloc) */  /* rmap,gmap,bmap should be 'desired' colors */  byte *pic24, *pp;  int  *cxtab, *pxtab;  int   y1Off, cyOff;  int   ex, ey, cx, cy, px, py, apx, apy, x1, y1;  int   cA, cB, cC, cD;  int   pA, pB, pC, pD;  int   retval, bperpix;  cA = cB = cC = cD = 0;  pp = pic24 = (byte *) malloc((size_t) (dwide * dhigh * 3));  if (!pic24) {    fprintf(stderr,"unable to malloc pic24 in 'Smooth24()'\n");    return pic24;  }  bperpix = (is24) ? 3 : 1;  /* decide which smoothing routine to use based on type of expansion */  if      (dwide <  swide && dhigh <  shigh)     retval = smoothXY(pic24, pic824, is24, swide, shigh, dwide, dhigh,		      rmap, gmap, bmap);  else if (dwide <  swide && dhigh >= shigh)     retval = smoothX (pic24, pic824, is24, swide, shigh, dwide, dhigh,		      rmap, gmap, bmap);  else if (dwide >= swide && dhigh <  shigh)     retval = smoothY (pic24, pic824, is24, swide, shigh, dwide, dhigh,		      rmap, gmap, bmap);  else {    /* dwide >= swide && dhigh >= shigh */    /* cx,cy = original pixel in pic824.  px,py = relative position        of pixel ex,ey inside of cx,cy as percentages +-50%, +-50%.         0,0 = middle of pixel */    /* we can save a lot of time by precomputing cxtab[] and pxtab[], both       dwide arrays of ints that contain values for the equations:         cx = (ex * swide) / dwide;         px = ((ex * swide * 100) / dwide) - (cx * 100) - 50; */    cxtab = (int *) malloc(dwide * sizeof(int));    if (!cxtab) { free(pic24);  return NULL; }    pxtab = (int *) malloc(dwide * sizeof(int));    if (!pxtab) { free(pic24);  free(cxtab);  return NULL; }    for (ex=0; ex<dwide; ex++) {      cxtab[ex] = (ex * swide) / dwide;      pxtab[ex] = (((ex * swide)* 100) / dwide) 	           - (cxtab[ex] * 100) - 50;    }        for (ey=0; ey<dhigh; ey++) {      byte *pptr, rA, gA, bA, rB, gB, bB, rC, gC, bC, rD, gD, bD;      ProgressMeter(0, (dhigh)-1, ey, "Smooth");      cy = (ey * shigh) / dhigh;      py = (((ey * shigh) * 100) / dhigh) - (cy * 100) - 50;      if (py<0) { y1 = cy-1;  if (y1<0) y1=0; }           else { y1 = cy+1;  if (y1>shigh-1) y1=shigh-1; }      cyOff = cy * swide * bperpix;    /* current line */      y1Off = y1 * swide * bperpix;    /* up or down one line, depending */      if ((ey&15) == 0) WaitCursor();      for (ex=0; ex<dwide; ex++) {	rA = rB = rC = rD = gA = gB = gC = gD = bA = bB = bC = bD = 0;	cx = cxtab[ex];	px = pxtab[ex];	if (px<0) { x1 = cx-1;  if (x1<0) x1=0; }	     else { x1 = cx+1;  if (x1>swide-1) x1=swide-1; }	if (is24) {	  pptr = pic824 + y1Off + x1*bperpix;   /* corner pixel */	  rA = *pptr++;  gA = *pptr++;  bA = *pptr++;	  pptr = pic824 + y1Off + cx*bperpix;   /* up/down center pixel */	  rB = *pptr++;  gB = *pptr++;  bB = *pptr++;	  pptr = pic824 + cyOff + x1*bperpix;   /* left/right center pixel */	  rC = *pptr++;  gC = *pptr++;  bC = *pptr++;	  pptr = pic824 + cyOff + cx*bperpix;   /* center pixel */	  rD = *pptr++;  gD = *pptr++;  bD = *pptr++;	}	else {  /* 8-bit picture */	  cA = pic824[y1Off + x1];   /* corner pixel */	  cB = pic824[y1Off + cx];   /* up/down center pixel */	  cC = pic824[cyOff + x1];   /* left/right center pixel */	  cD = pic824[cyOff + cx];   /* center pixel */	}	 	/* quick check */	if (!is24 && cA == cB && cB == cC && cC == cD) {	  /* set this pixel to the same color as in pic8 */	  *pp++ = rmap[cD];  *pp++ = gmap[cD];  *pp++ = bmap[cD];	}	else {	  /* compute weighting factors */	  apx = abs(px);  apy = abs(py);	  pA = (apx * apy) / 100;	  pB = (apy * (100 - apx)) / 100;	  pC = (apx * (100 - apy)) / 100;	  pD = 100 - (pA + pB + pC);	  if (is24) {	    *pp++ = ((int) (pA * rA))/100 + ((int) (pB * rB))/100 + 	            ((int) (pC * rC))/100 + ((int) (pD * rD))/100;	    *pp++ = ((int) (pA * gA))/100 + ((int) (pB * gB))/100 + 	            ((int) (pC * gC))/100 + ((int) (pD * gD))/100;	    *pp++ = ((int) (pA * bA))/100 + ((int) (pB * bB))/100 + 	            ((int) (pC * bC))/100 + ((int) (pD * bD))/100;	  }	  else {  /* 8-bit pic */	    *pp++ = ((int) (pA * rmap[cA]))/100 + ((int)(pB * rmap[cB]))/100 + 	            ((int) (pC * rmap[cC]))/100 + ((int)(pD * rmap[cD]))/100;	    *pp++ = ((int) (pA * gmap[cA]))/100 + ((int)(pB * gmap[cB]))/100 + 	            ((int) (pC * gmap[cC]))/100 + ((int)(pD * gmap[cD]))/100;	    *pp++ = ((int)(pA * bmap[cA]))/100 + ((int)(pB * bmap[cB]))/100 +   	            ((int)(pC * bmap[cC]))/100 + ((int)(pD * bmap[cD]))/100;	  }	}      }    }    free(cxtab);      free(pxtab);    retval = 0;    /* okay */  }  if (retval) {    /* one of the Smooth**() methods failed */    free(pic24);    pic24 = (byte *) NULL;  }  return pic24;}/***************************************************/static int smoothX(pic24, pic824, is24, swide, shigh, dwide, dhigh, 		   rmap, gmap, bmap)byte *pic24, *pic824, *rmap, *gmap, *bmap;int   is24, swide, shigh, dwide, dhigh;{  byte *cptr, *cptr1;  int  i, j;  int  *lbufR, *lbufG, *lbufB;  int  pixR, pixG, pixB, bperpix;  int  pcnt0, pcnt1, lastpix, pixcnt, thisline, ypcnt;  int  *pixarr, *paptr;  /* returns '0' if okay, '1' if failed (malloc) */  /* for case where pic8 is shrunk horizontally and stretched vertically     maps pic8 into an dwide * dhigh 24-bit picture.  Only works correctly     when swide>=dwide and shigh<=dhigh */  /* malloc some arrays */  lbufR  = (int *) calloc((size_t) swide,   sizeof(int));  lbufG  = (int *) calloc((size_t) swide,   sizeof(int));  lbufB  = (int *) calloc((size_t) swide,   sizeof(int));  pixarr = (int *) calloc((size_t) swide+1, sizeof(int));  if (!lbufR || !lbufG || !lbufB || !pixarr) {    if (lbufR)  free(lbufR);    if (lbufG)  free(lbufG);    if (lbufB)  free(lbufB);    if (pixarr) free(pixarr);    return 1;  }  bperpix = (is24) ? 3 : 1;  for (j=0; j<=swide; j++)     pixarr[j] = (j*dwide + (15*swide)/16) / swide;  cptr = pic824;  cptr1 = cptr + swide * bperpix;  for (i=0; i<dhigh; i++) {    ProgressMeter(0, (dhigh)-1, i, "Smooth");    if ((i&15) == 0) WaitCursor();    ypcnt = (((i*shigh)<<6) / dhigh) - 32;    if (ypcnt<0) ypcnt = 0;    pcnt1 = ypcnt & 0x3f;                     /* 64ths of NEXT line to use */    pcnt0 = 64 - pcnt1;                       /* 64ths of THIS line to use */    thisline = ypcnt>>6;    cptr  = pic824 + thisline * swide * bperpix;    if (thisline+1 < shigh) cptr1 = cptr + swide * bperpix;    else cptr1 = cptr;    if (is24) {      for (j=0; j<swide; j++) {	lbufR[j] = ((int) ((*cptr++ * pcnt0) + (*cptr1++ * pcnt1))) >> 6;	lbufG[j] = ((int) ((*cptr++ * pcnt0) + (*cptr1++ * pcnt1))) >> 6;	lbufB[j] = ((int) ((*cptr++ * pcnt0) + (*cptr1++ * pcnt1))) >> 6;      }    }     else {  /* 8-bit input pic */      for (j=0; j<swide; j++, cptr++, cptr1++) {	lbufR[j] = ((int)((rmap[*cptr]* pcnt0) + (rmap[*cptr1]* pcnt1))) >> 6;	lbufG[j] = ((int)((gmap[*cptr]* pcnt0) + (gmap[*cptr1]* pcnt1))) >> 6;	lbufB[j] = ((int)((bmap[*cptr]* pcnt0) + (bmap[*cptr1]* pcnt1))) >> 6;      }    }    pixR = pixG = pixB = pixcnt = lastpix = 0;    for (j=0, paptr=pixarr; j<=swide; j++,paptr++) {      if (*paptr != lastpix) {   /* write a pixel to pic24 */	if (!pixcnt) pixcnt = 1;    /* this NEVER happens:  quiets compilers */	*pic24++ = pixR / pixcnt;	*pic24++ = pixG / pixcnt;	*pic24++ = pixB / pixcnt;	lastpix = *paptr;	pixR = pixG = pixB = pixcnt = 0;      }      if (j<swide) {	pixR += lbufR[j];	pixG += lbufG[j];	pixB += lbufB[j];	pixcnt++;      }    }  }  free(lbufR);  free(lbufG);  free(lbufB);  free(pixarr);  return 0;}	      /***************************************************/static int smoothY(pic24, pic824, is24, swide, shigh, dwide, dhigh,		   rmap, gmap, bmap)byte *pic24, *pic824, *rmap, *gmap, *bmap;int   is24, swide, shigh, dwide, dhigh;{  byte *clptr, *cptr, *cptr1;  int  i, j, bperpix;  int  *lbufR, *lbufG, *lbufB, *pct0, *pct1, *cxarr, *cxptr;  int  lastline, thisline, linecnt;  int  retval;  /* returns '0' if okay, '1' if failed (malloc) */  /* for case where pic8 is shrunk vertically and stretched horizontally     maps pic8 into a dwide * dhigh 24-bit picture.  Only works correctly     when swide<=dwide and shigh>=dhigh */  retval = 0;   /* no probs, yet... */  bperpix = (is24) ? 3 : 1;  lbufR = lbufG = lbufB = pct0 = pct1 = cxarr = NULL;  lbufR = (int *) calloc((size_t) dwide, sizeof(int));  lbufG = (int *) calloc((size_t) dwide, sizeof(int));  lbufB = (int *) calloc((size_t) dwide, sizeof(int));  pct0  = (int *) calloc((size_t) dwide, sizeof(int));  pct1  = (int *) calloc((size_t) dwide, sizeof(int));  cxarr = (int *) calloc((size_t) dwide, sizeof(int));  if (!lbufR || !lbufG || !lbufB || !pct0 || ! pct1 || !cxarr) {    retval = 1;    goto smyexit;  }  for (i=0; i<dwide; i++) {                /* precompute some handy tables */    int cx64;    cx64 = (((i * swide) << 6) / dwide) - 32;    if (cx64<0) cx64 = 0;    pct1[i] = cx64 & 0x3f;    pct0[i] = 64 - pct1[i];    cxarr[i] = cx64 >> 6;  }  lastline = linecnt = 0;  for (i=0, clptr=pic824; i<=shigh; i++, clptr+=swide*bperpix) {    ProgressMeter(0, shigh, i, "Smooth");    if ((i&15) == 0) WaitCursor();    thisline = (i * dhigh + (15*shigh)/16) / shigh;    if (thisline != lastline) {  /* copy a line to pic24 */      for (j=0; j<dwide; j++) {	*pic24++ = lbufR[j] / linecnt;	*pic24++ = lbufG[j] / linecnt;	*pic24++ = lbufB[j] / linecnt;      }      xvbzero( (char *) lbufR, dwide * sizeof(int));  /* clear out line bufs */      xvbzero( (char *) lbufG, dwide * sizeof(int));      xvbzero( (char *) lbufB, dwide * sizeof(int));      linecnt = 0;  lastline = thisline;    }    for (j=0, cxptr=cxarr; j<dwide; j++, cxptr++) {      cptr  = clptr + *cxptr * bperpix;      if (*cxptr < swide-1) cptr1 = cptr + 1*bperpix;                       else cptr1 = cptr;      if (is24) {	lbufR[j] += ((int)((*cptr++ * pct0[j]) + (*cptr1++ * pct1[j]))) >> 6;	lbufG[j] += ((int)((*cptr++ * pct0[j]) + (*cptr1++ * pct1[j]))) >> 6;	lbufB[j] += ((int)((*cptr++ * pct0[j]) + (*cptr1++ * pct1[j]))) >> 6;      }      else {  /* 8-bit input pic */	lbufR[j] += ((int)((rmap[*cptr]*pct0[j])+(rmap[*cptr1]*pct1[j]))) >> 6;	lbufG[j] += ((int)((gmap[*cptr]*pct0[j])+(gmap[*cptr1]*pct1[j]))) >> 6;	lbufB[j] += ((int)((bmap[*cptr]*pct0[j])+(bmap[*cptr1]*pct1[j]))) >> 6;      }    }       linecnt++;  } smyexit:  if (lbufR) free(lbufR);  if (lbufG) free(lbufG);  if (lbufB) free(lbufB);  if (pct0)  free(pct0);  if (pct1)  free(pct1);  if (cxarr) free(cxarr);  return retval;}	      /***************************************************/static int smoothXY(pic24, pic824, is24, swide, shigh, dwide, dhigh, 		    rmap, gmap, bmap)byte *pic24, *pic824, *rmap, *gmap, *bmap;int   is24, swide, shigh, dwide, dhigh;{  byte *cptr;  int  i,j;  int  *lbufR, *lbufG, *lbufB;  int  pixR, pixG, pixB, bperpix;  int  lastline, thisline, lastpix, linecnt, pixcnt;  int  *pixarr, *paptr;  /* returns '0' if okay, '1' if failed (malloc) */  /* shrinks pic8 into a dwide * dhigh 24-bit picture.  Only works correctly     when swide>=dwide and shigh>=dhigh (ie, the picture is shrunk on both

⌨️ 快捷键说明

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