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

📄 xvsmooth.c

📁 音视频编解码的H.263协议-C语言编写
💻 C
📖 第 1 页 / 共 2 页
字号:
     axes) */  /* 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;  lastline = linecnt = pixR = pixG = pixB = 0;  cptr = pic824;  for (i=0; i<=shigh; i++) {    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 */      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;    /* NEVER happens: quiets compilers */	  *pic24++ = (pixR/linecnt) / pixcnt;	  *pic24++ = (pixG/linecnt) / pixcnt;	  *pic24++ = (pixB/linecnt) / pixcnt;	  lastpix = *paptr;	  pixR = pixG = pixB = pixcnt = 0;	}	if (j<swide) {	  pixR += lbufR[j];	  pixG += lbufG[j];	  pixB += lbufB[j];	  pixcnt++;	}      }      lastline = thisline;      xvbzero( (char *) lbufR, swide * sizeof(int));  /* clear out line bufs */      xvbzero( (char *) lbufG, swide * sizeof(int));      xvbzero( (char *) lbufB, swide * sizeof(int));      linecnt = 0;    }    if (i<shigh) {      if (is24) {	for (j=0; j<swide; j++) {	  lbufR[j] += *cptr++;	  lbufG[j] += *cptr++;	  lbufB[j] += *cptr++;	}      }      else {	for (j=0; j<swide; j++, cptr++) {	  lbufR[j] += rmap[*cptr];	  lbufG[j] += gmap[*cptr];	  lbufB[j] += bmap[*cptr];	}      }      linecnt++;    }  }  free(lbufR);  free(lbufG);  free(lbufB);  free(pixarr);  return 0;}	      /********************************************/byte *DoColorDither(pic24, pic8, w, h, rmap, gmap, bmap, 		    rdisp, gdisp, bdisp, maplen)     byte *pic24, *pic8, *rmap, *gmap, *bmap, *rdisp, *gdisp, *bdisp;     int   w, h, maplen;{  /* takes a 24 bit picture, of size w*h, dithers with the colors in     rdisp, gdisp, bdisp (which have already been allocated),     and generates an 8-bit w*h image, which it returns.       ignores input value 'pic8'     returns NULL on error      note: the rdisp,gdisp,bdisp arrays should be the 'displayed' colors,     not the 'desired' colors     if pic24 is NULL, uses the passed-in pic8 (an 8-bit image) as     the source, and the rmap,gmap,bmap arrays as the desired colors */  byte *np, *ep, *newpic;   short *cache;  int r2, g2, b2;  int *thisline, *nextline, *thisptr, *nextptr, *tmpptr;  int  i, j, rerr, gerr, berr, pwide3;  int  imax, jmax;  int key;  long cnt1, cnt2;  int fserrmap[512];   /* -255 .. 0 .. +255 */  /* compute somewhat non-linear floyd-steinberg error mapping table */  for (i=j=0; i<=0x40; i++,j++)     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }  for (     ; i<0x80; i++, j += !(i&1) ? 1 : 0)     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }  for (     ; i<=0xff; i++)     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }  cnt1 = cnt2 = 0;  pwide3 = w*3;  imax = h-1;  jmax = w-1;  ep = (pic24) ? pic24 : pic8;  /* attempt to malloc things */  newpic = (byte *)  malloc((size_t) (w * h));  cache  = (short *) calloc((size_t) (2<<14), sizeof(short));  thisline = (int *) malloc(pwide3 * sizeof(int));  nextline = (int *) malloc(pwide3 * sizeof(int));  if (!cache || !newpic || !thisline || !nextline) {     if (newpic)   free(newpic);    if (cache)    free(cache);    if (thisline) free(thisline);    if (nextline) free(nextline);    return (byte *) NULL;  }  np = newpic;  /* get first line of picture */  if (pic24) {    for (j=pwide3, tmpptr=nextline; j; j--, ep++)      *tmpptr++ = (int) *ep;  }  else {    for (j=w, tmpptr=nextline; j; j--, ep++) {      *tmpptr++ = (int) rmap[*ep];      *tmpptr++ = (int) gmap[*ep];      *tmpptr++ = (int) bmap[*ep];    }  }  for (i=0; i<h; i++) {    ProgressMeter(0, h-1, i, "Dither");    if ((i&15) == 0) WaitCursor();    tmpptr = thisline;  thisline = nextline;  nextline = tmpptr;   /* swap */    if (i!=imax) {  /* get next line */      if (!pic24)	for (j=w, tmpptr=nextline; j; j--, ep++) {	  *tmpptr++ = (int) rmap[*ep];	  *tmpptr++ = (int) gmap[*ep];	  *tmpptr++ = (int) bmap[*ep];	}      else	for (j=pwide3, tmpptr=nextline; j; j--, ep++) *tmpptr++ = (int) *ep;    }    /* dither a line */    for (j=0, thisptr=thisline, nextptr=nextline; j<w; j++,np++) {      int k, d, mind, closest;      r2 = *thisptr++;  g2 = *thisptr++;  b2 = *thisptr++;      /* map r2,g2,b2 components (could be outside 0..255 range) 	 into 0..255 range */            if (r2<0 || g2<0 || b2<0) {   /* are there any negatives in RGB? */	if (r2<g2) { if (r2<b2) k = 0; else k = 2; }	else { if (g2<b2) k = 1; else k = 2; }	switch (k) {	case 0:  g2 -= r2;  b2 -= r2;  d = (abs(r2) * 3) / 2;    /* RED */	         r2 = 0;  	         g2 = (g2>d) ? g2 - d : 0;	         b2 = (b2>d) ? b2 - d : 0;	         break;	case 1:  r2 -= g2;  b2 -= g2;  d = (abs(g2) * 3) / 2;    /* GREEN */	         r2 = (r2>d) ? r2 - d : 0;	         g2 = 0;  	         b2 = (b2>d) ? b2 - d : 0;	         break;	case 2:  r2 -= b2;  g2 -= b2;  d = (abs(b2) * 3) / 2;    /* BLUE */	         r2 = (r2>d) ? r2 - d : 0;	         g2 = (g2>d) ? g2 - d : 0;	         b2 = 0;  	         break;	}      }      if (r2>255 || g2>255 || b2>255) {   /* any overflows in RGB? */	if (r2>g2) { if (r2>b2) k = 0; else k = 2; }              else { if (g2>b2) k = 1; else k = 2; }	switch (k) {	case 0:   g2 = (g2*255)/r2;  b2 = (b2*255)/r2;  r2=255;  break;	case 1:   r2 = (r2*255)/g2;  b2 = (b2*255)/g2;  g2=255;  break;	case 2:   r2 = (r2*255)/b2;  g2 = (g2*255)/b2;  b2=255;  break;	}      }      key = ((r2&0xf8)<<6) | ((g2&0xf8)<<1) | (b2>>4);      if (key >= (2<<14)) FatalError("'key' overflow in DoColorDither()");      if (cache[key]) { *np = (byte) (cache[key] - 1);  cnt1++;	}      else {	/* not in cache, have to search the colortable */	cnt2++;        mind = 10000;	for (k=closest=0; k<maplen && mind>7; k++) {	  d = abs(r2 - rdisp[k])	    + abs(g2 - gdisp[k]) 	    + abs(b2 - bdisp[k]);	  if (d<mind) { mind = d;  closest = k; }	}	cache[key] = closest + 1;	*np = closest;      }      /* propogate the error */      rerr = r2 - rdisp[*np];      gerr = g2 - gdisp[*np];      berr = b2 - bdisp[*np];      RANGE(rerr, -255, 255);      RANGE(gerr, -255, 255);      RANGE(berr, -255, 255);      rerr = fserrmap[256+rerr];      gerr = fserrmap[256+gerr];      berr = fserrmap[256+berr];      if (j!=jmax) {  /* adjust RIGHT pixel */	thisptr[0] += (rerr*7)/16;	thisptr[1] += (gerr*7)/16;	thisptr[2] += (berr*7)/16;      }            if (i!=imax) {	/* do BOTTOM pixel */	nextptr[0] += (rerr*5)/16;	nextptr[1] += (gerr*5)/16;	nextptr[2] += (berr*5)/16;	if (j>0) {  /* do BOTTOM LEFT pixel */	  nextptr[-3] += (rerr*3)/16;	  nextptr[-2] += (gerr*3)/16;	  nextptr[-1] += (berr*3)/16;	}	if (j!=jmax) {  /* do BOTTOM RIGHT pixel */	  nextptr[3] += rerr/16;	  nextptr[4] += gerr/16;	  nextptr[5] += berr/16;	}	nextptr += 3;      }    }  }  free(thisline);  free(nextline);  free(cache);  return newpic;}/********************************************/byte *Do332ColorDither(pic24, pic8, w, h, rmap, gmap, bmap, 		    rdisp, gdisp, bdisp, maplen)     byte *pic24, *pic8, *rmap, *gmap, *bmap, *rdisp, *gdisp, *bdisp;     int   w, h, maplen;{  /* some sort of color dither optimized for the 332 std cmap */  /* takes a 24 bit picture, of size w*h, dithers with the colors in     rdisp, gdisp, bdisp (which have already been allocated),     and generates an 8-bit w*h image, which it returns.       ignores input value 'pic8'     returns NULL on error      note: the rdisp,gdisp,bdisp arrays should be the 'displayed' colors,     not the 'desired' colors     if pic24 is NULL, uses the passed-in pic8 (an 8-bit image) as     the source, and the rmap,gmap,bmap arrays as the desired colors */  byte *np, *ep, *newpic;   int r2, g2, b2;  int *thisline, *nextline, *thisptr, *nextptr, *tmpptr;  int  i, j, rerr, gerr, berr, pwide3;  int  imax, jmax;  long cnt1, cnt2;  int  fserrmap[512];   /* -255 .. 0 .. +255 */  /* compute somewhat non-linear floyd-steinberg error mapping table */  for (i=j=0; i<=0x40; i++,j++)     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }  for (     ; i<0x80; i++, j += !(i&1) ? 1 : 0)     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }  for (     ; i<=0xff; i++)     { fserrmap[256+i] = j;  fserrmap[256-i] = -j; }  cnt1 = cnt2 = 0;  pwide3 = w*3;  imax = h-1;  jmax = w-1;  /* attempt to malloc things */  newpic   = (byte *) malloc((size_t) (w * h));  thisline = (int *)  malloc(pwide3 * sizeof(int));  nextline = (int *)  malloc(pwide3 * sizeof(int));  if (!newpic || !thisline || !nextline) {     if (newpic)   free(newpic);    if (thisline) free(thisline);    if (nextline) free(nextline);    return (byte *) NULL;  }  np = newpic;  ep = (pic24) ? pic24 : pic8;  /* get first line of picture */  if (pic24) {    for (j=pwide3, tmpptr=nextline; j; j--, ep++) *tmpptr++ = (int) *ep;  }  else {    for (j=w, tmpptr=nextline; j; j--, ep++) {      *tmpptr++ = (int) rmap[*ep];      *tmpptr++ = (int) gmap[*ep];      *tmpptr++ = (int) bmap[*ep];    }  }  for (i=0; i<h; i++) {    np = newpic + i*w;    ProgressMeter(0, h-1, i, "Dither");    if ((i&127) == 0) WaitCursor();    tmpptr = thisline;  thisline = nextline;  nextline = tmpptr;   /* swap */    if (i!=imax) {  /* get next line */      if (!pic24)	for (j=w, tmpptr=nextline; j; j--, ep++) {	  *tmpptr++ = (int) rmap[*ep];	  *tmpptr++ = (int) gmap[*ep];	  *tmpptr++ = (int) bmap[*ep];	}      else	for (j=pwide3, tmpptr=nextline; j; j--, ep++) *tmpptr++ = (int) *ep;    }    /* dither a line, doing odd-lines right-to-left (serpentine) */    thisptr = (i&1) ? thisline + w*3 - 3 : thisline;    nextptr = (i&1) ? nextline + w*3 - 3 : nextline;    if (i&1) np += w-1;    for (j=0; j<w; j++) {      int k, d, mind, closest, rb,gb,bb;      r2 = *thisptr++;  g2 = *thisptr++;  b2 = *thisptr++;      if (i&1) thisptr -= 6;  /* move left */      rb = (r2 + 0x10);    /* round top 3 bits */      RANGE(rb,0,255);      rb = rb & 0xe0;      gb = (g2 + 0x10);    /* round 3 bits */      RANGE(gb,0,255);      gb = gb & 0xe0;      bb = (b2 + 0x20);    /* round 2 bits */      RANGE(bb,0,255);      bb = bb & 0xc0;            *np = rb | (gb>>3) | (bb>>6);      /* propogate the error */      rerr = r2 - rdisp[*np];      gerr = g2 - gdisp[*np];      berr = b2 - bdisp[*np];      RANGE(rerr, -255, 255);      RANGE(gerr, -255, 255);      RANGE(berr, -255, 255);      rerr = fserrmap[256+rerr];      gerr = fserrmap[256+gerr];      berr = fserrmap[256+berr];      if (j!=jmax) {  /* adjust LEFT/RIGHT pixel */	thisptr[0] += (rerr/2);  rerr -= (rerr/2);	thisptr[1] += (gerr/2);  gerr -= (gerr/2);	thisptr[2] += (berr/2);  berr -= (berr/2);      }      if (i!=imax) { /* adjust BOTTOM pixel */	nextptr[0] += rerr;    /* possibly all err if we're at l/r edge */	nextptr[1] += gerr;	nextptr[2] += berr;      }      if (i&1) { nextptr -= 3;  np--; }          else { nextptr += 3;  np++; }    }  }  free(thisline);  free(nextline);  return newpic;}

⌨️ 快捷键说明

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