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

📄 dl1quant.cpp

📁 MPEG4解码源代码(包含完整的工程文件)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

LOCAL void closest_color(int index, int level) 
{
    int i;

    if (rgb_table[level][index].children) {
		for (i = 7; i >= 0; i--) {
			if (rgb_table[level][index].children & (1 << i)) {
				closest_color((index << 3) + i, level + 1);
			}
		}
	}

    if (rgb_table[level][index].pixel_count) {
		slong dist, r_dist, g_dist, b_dist;
		uchar pal_num = rgb_table[level][index].palette_index;

		/* Determine if this color is "closest". */
		r_dist = palette[0][pal_num] - c_info.red;
		g_dist = palette[1][pal_num] - c_info.green;
		b_dist = palette[2][pal_num] - c_info.blue;
		
		dist = squares[r_dist] + squares[g_dist] + squares[b_dist];

		if (dist < (slong)c_info.distance) {
			c_info.distance = dist;
			c_info.palette_index = pal_num;
		}
    }
}

/* returns 1 on success, 0 on failure */
LOCAL int quantize_image(uchar *in, uchar *out, int width, int height, int dither) 
{
	if (!dither) {
		ulong i=0;
		ulong pixels = width * height;
		ushort level=0;
		ushort index=0;
		uchar tmp_r=0;
		uchar tmp_g=0;
		uchar tmp_b=0;
		uchar cube=0;
		uchar *lookup=NULL;

		lookup = (BYTE*)malloc(sizeof(char) * 32768);
		if (lookup == NULL)
			return 0;

		for (i = 0; i < 32768; i++)
			if (rgb_table[5][i].pixel_count) {
			tmp_r = (BYTE)((i & 0x4000) >> 7 | (i & 0x0800) >> 5 |
				(i & 0x0100) >> 3 | (i & 0x0020) >> 1 |
				(i & 0x0004) << 1);
			tmp_g = (BYTE)((i & 0x2000) >> 6 | (i & 0x0400) >> 4 |
				(i & 0x0080) >> 2 | (i & 0x0010) >> 0 |
				(i & 0x0002) << 2);
			tmp_b = (BYTE)((i & 0x1000) >> 5 | (i & 0x0200) >> 3 |
				(i & 0x0040) >> 1 | (i & 0x0008) << 1 |
				(i & 0x0001) << 3);
	#ifdef QUAL2
			lookup[i] = bestcolor(tmp_r, tmp_g, tmp_b);
	#else
			c_info.red   = tmp_r + 4;
			c_info.green = tmp_g + 4;
			c_info.blue  = tmp_b + 4;
			level = 0;
			index = 0;
			for (;;) {
				cube = (tmp_r&128) >> 5 | (tmp_g&128) >> 6 | (tmp_b&128) >> 7;
				if ((rgb_table[level][index].children & (1 << cube)) == 0) {
				c_info.distance = (ULONG)~0L;
				closest_color(index, level);
				lookup[i] = c_info.palette_index;
				break;
				}
				level++;
				index = (index << 3) + cube;
				tmp_r <<= 1;
				tmp_g <<= 1;
				tmp_b <<= 1;
			}
	#endif
			}

		for (i = 0; i < pixels; i++) {
	#ifdef FAST
			out[i] = lookup[dl_image[i]];
	#else
			out[i] = lookup[r_offset[in[0]] + g_offset[in[1]] + b_offset[in[2]]];
			in += 3;
	#endif
		}

		free(lookup);

	} else { // dither

	#if defined(DITHER2) || defined(DITHER4)
		slong i=0;
		slong j=0;
		slong r_pix=0;
		slong g_pix=0;
		slong b_pix=0;
		slong offset=0;
		slong dir=0;
		slong two_val=0;
		slong odd_scanline = 0;
		slong err_len = (width + 2) * 3;

		uchar *range_tbl = NULL; 
		uchar *range = NULL;

		sshort *lookup = NULL;
		sshort *erowerr = NULL;
		sshort *orowerr = NULL;
		sshort *thisrowerr = NULL;
		sshort *nextrowerr = NULL;

		schar *dith_max_tbl = NULL;
		schar *dith_max = NULL;

		lookup = (sshort *)malloc(sizeof(short) * 32768);
		erowerr = (sshort *)malloc(sizeof(short) * err_len);
		orowerr = (sshort *)malloc(sizeof(short) * err_len);
		range_tbl = (BYTE*)malloc(3 * 256);
		range = range_tbl + 256;
		dith_max_tbl= (schar *)malloc(512);
		dith_max = dith_max_tbl + 256;

		if (range_tbl == NULL || lookup == NULL ||
			erowerr == NULL || orowerr == NULL || dith_max_tbl == NULL) {
			if (range_tbl != NULL) {
				free(range_tbl);
				range_tbl=NULL;
			}
			if (lookup != NULL) {
				free(lookup);
				lookup=NULL;
			}
			if (erowerr != NULL) {
				free(erowerr);
				erowerr=NULL;
			}
			if (orowerr != NULL) {
				free(orowerr);
				orowerr=NULL;
			}
			if (dith_max_tbl != NULL) {
				free(dith_max_tbl);
				dith_max_tbl=NULL;
			}
			return 0;
		}

		for (i = 0; i < err_len; i++)
			erowerr[i] = 0;

		for (i = 0; i < 32768; i++)
			lookup[i] = -1;

		for (i = 0; i < 256; i++) {
			range_tbl[i] = 0;
			range_tbl[i + 256] = (uchar) i;
			range_tbl[i + 512] = 255;
		}

		for (i = 0; i < 256; i++) {
			dith_max_tbl[i] = -DITHER_MAX;
			dith_max_tbl[i + 256] = DITHER_MAX;
		}
		for (i = -DITHER_MAX; i <= DITHER_MAX; i++)
			dith_max_tbl[i + 256] = (schar)i;

		for (i = 0 ; i < height; i++) {
			if (odd_scanline) {
				dir = -1;
				in  += (width - 1) * 3;
				out += (width - 1);
				thisrowerr = orowerr + 3;
				nextrowerr = erowerr + width * 3;
			} else {
				dir = 1;
				thisrowerr = erowerr + 3;
				nextrowerr = orowerr + width * 3;
			}

			nextrowerr[0] = nextrowerr[1] = nextrowerr[2] = 0;
			
			for (j = 0; j < width; j++) {

		#ifdef DITHER2
				r_pix = range[(thisrowerr[0] >> 1) + in[0]];
				g_pix = range[(thisrowerr[1] >> 1) + in[1]];
				b_pix = range[(thisrowerr[2] >> 1) + in[2]];
		#else
				r_pix = range[((thisrowerr[0] + 8) >> 4) + in[0]];
				g_pix = range[((thisrowerr[1] + 8) >> 4) + in[1]];
				b_pix = range[((thisrowerr[2] + 8) >> 4) + in[2]];
		#endif
				offset = (r_pix&248) << 7 | (g_pix&248) << 2 | b_pix >> 3;
				if (lookup[offset] < 0)
					lookup[offset] = bestcolor(r_pix, g_pix, b_pix);
				*out = (BYTE)lookup[offset];
				r_pix = dith_max[r_pix - palette[0][lookup[offset]]];
				g_pix = dith_max[g_pix - palette[1][lookup[offset]]];
				b_pix = dith_max[b_pix - palette[2][lookup[offset]]];

		#ifdef DITHER2
				nextrowerr[0  ]  = (short)r_pix;
				thisrowerr[0+3] += (short)r_pix;
				nextrowerr[1  ]  = (short)g_pix;
				thisrowerr[1+3] += (short)g_pix;
				nextrowerr[2  ]  = (short)b_pix;
				thisrowerr[2+3] += (short)b_pix;
		#else
				two_val = r_pix * 2;
				nextrowerr[0-3]  = r_pix;
				r_pix += two_val;
				nextrowerr[0+3] += r_pix;
				r_pix += two_val;
				nextrowerr[0  ] += r_pix;
				r_pix += two_val;
				thisrowerr[0+3] += r_pix;
				two_val = g_pix * 2;
				nextrowerr[1-3]  = g_pix;
				g_pix += two_val;
				nextrowerr[1+3] += g_pix;
				g_pix += two_val;
				nextrowerr[1  ] += g_pix;
				g_pix += two_val;
				thisrowerr[1+3] += g_pix;
				two_val = b_pix * 2;
				nextrowerr[2-3]  = b_pix;
				b_pix += two_val;
				nextrowerr[2+3] += b_pix;
				b_pix += two_val;
				nextrowerr[2  ] += b_pix;
				b_pix += two_val;
				thisrowerr[2+3] += b_pix;
		#endif
				thisrowerr += 3;
				nextrowerr -= 3;
				in  += dir * 3;
				out += dir;
			}

			if ((i % 2) == 1) {
				in  += (width + 1) * 3;
				out += (width + 1);
			}

			odd_scanline = !odd_scanline;
		}

		free(range_tbl);
		free(lookup);
		free(erowerr);
		free(orowerr);
		free(dith_max_tbl);
	#else
		slong i =0; 
		slong j=0; 
		slong r_pix=0;
		slong g_pix=0;
		slong b_pix=0;
		slong r_err=0;
		slong g_err=0;
		slong b_err=0;
		slong offset=0;

		uchar *range_tbl = (BYTE*)malloc(3 * 256), *range = range_tbl + 256;
		sshort *lookup = (sshort *)malloc(sizeof(short) * 32768);

		if (range_tbl == NULL || lookup == NULL) {
			if (range_tbl != NULL)
			free(range_tbl);
			if (lookup != NULL)
			free(lookup);
			return 0;
		}

		for (i = 0; i < 32768; i++)
			lookup[i] = -1;

		for (i = 0; i < 256; i++) {
			range_tbl[i] = 0;
			range_tbl[i + 256] = (uchar) i;
			range_tbl[i + 512] = 255;
		}

		for (i = 0; i < height; i++) {
			r_err = g_err = b_err = 0;
			for (j = width - 1; j >= 0; j--) {
				r_pix = range[(r_err >> 1) + in[0]];
				g_pix = range[(g_err >> 1) + in[1]];
				b_pix = range[(b_err >> 1) + in[2]];
				
				offset = (r_pix&248) << 7 | (g_pix&248) << 2 | b_pix >> 3;

				if (lookup[offset] < 0)
					lookup[offset] = bestcolor(r_pix, g_pix, b_pix);

				*out++ = (BYTE)lookup[offset];

				r_err = r_pix - palette[0][lookup[offset]];
				g_err = g_pix - palette[1][lookup[offset]];
				b_err = b_pix - palette[2][lookup[offset]];

				in += 3;
			}
		}

		free(range_tbl);
		free(lookup);
	#endif
    }

    return 1;
}

LOCAL int bestcolor(int r, int g, int b) 
{
    ulong i=0;
	ulong bestcolor=0;
	ulong curdist=0;
	ulong mindist=0;
    slong rdist=0;
	slong gdist=0;
	slong bdist=0;

    r = (r & 248) + 4;
    g = (g & 248) + 4;
    b = (b & 248) + 4;
    mindist = 200000;

	for (i = 0; i < (ulong)tot_colors; i++) {
		rdist = palette[0][i] - r;
		gdist = palette[1][i] - g;
		bdist = palette[2][i] - b;
		curdist = squares[rdist] + squares[gdist] + squares[bdist];

		if (curdist < mindist) {
			mindist = curdist;
			bestcolor = i;
		}
	}
    return bestcolor;
}

#ifdef __cplusplus
}
#endif

⌨️ 快捷键说明

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