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

📄 gd_png.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			}			break;		default:			/* Palette image, or something coerced to be one */			for (h = 0; h < height; ++h) {				for (w = 0; w < width; ++w) {					register png_byte idx = row_pointers[h][w];					im->pixels[h][w] = idx;					open[idx] = 0;				}			}	}#ifdef DEBUG	if (!im->trueColor) {		for (i = num_palette; i < gdMaxColors; ++i) {			if (!open[i]) {				php_gd_error("gd-png warning: image data references out-of-range color index (%d)\n", i);			}		}	}#endif	if (palette_allocated) {		gdFree(palette);	}	gdFree(image_data);	gdFree(row_pointers);	return im;}void gdImagePngEx (gdImagePtr im, FILE * outFile, int level){	gdIOCtx *out = gdNewFileCtx(outFile);	gdImagePngCtxEx(im, out, level);	out->gd_free(out);}void gdImagePng (gdImagePtr im, FILE * outFile){	gdIOCtx *out = gdNewFileCtx(outFile);  	gdImagePngCtxEx(im, out, -1);	out->gd_free(out);}void * gdImagePngPtr (gdImagePtr im, int *size){	void *rv;	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);	gdImagePngCtxEx(im, out, -1);	rv = gdDPExtractData(out, size);	out->gd_free(out);	return rv;}void * gdImagePngPtrEx (gdImagePtr im, int *size, int level){	void *rv;	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);	gdImagePngCtxEx(im, out, level);	rv = gdDPExtractData(out, size);	out->gd_free(out);	return rv;}void gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile){	gdImagePngCtxEx(im, outfile, -1);}/* This routine is based in part on code from Dale Lutz (Safe Software Inc.) *  and in part on demo code from Chapter 15 of "PNG: The Definitive Guide" *  (http://www.cdrom.com/pub/png/pngbook.html). */void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level){	int i, j, bit_depth = 0, interlace_type;	int width = im->sx;	int height = im->sy;	int colors = im->colorsTotal;	int *open = im->open;	int mapping[gdMaxColors];	/* mapping[gd_index] == png_index */	png_byte trans_values[256];	png_color_16 trans_rgb_value;	png_color palette[gdMaxColors];	png_structp png_ptr;	png_infop info_ptr;	volatile int transparent = im->transparent;	volatile int remap = FALSE;#ifndef PNG_SETJMP_NOT_SUPPORTED	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, &gdPngJmpbufStruct, gdPngErrorHandler, NULL);#else	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);#endif	if (png_ptr == NULL) {		php_gd_error("gd-png error: cannot allocate libpng main struct\n");		return;	}	info_ptr = png_create_info_struct(png_ptr);	if (info_ptr == NULL) {		php_gd_error("gd-png error: cannot allocate libpng info struct\n");		png_destroy_write_struct (&png_ptr, (png_infopp) NULL);		return;    }#ifndef PNG_SETJMP_NOT_SUPPORTED	if (setjmp (gdPngJmpbufStruct.jmpbuf)) {		php_gd_error("gd-png error: setjmp returns error condition\n");		png_destroy_write_struct (&png_ptr, &info_ptr);		return;	}#endif	png_set_write_fn(png_ptr, (void *) outfile, gdPngWriteData, gdPngFlushData);	/* This is best for palette images, and libpng defaults to it for	 * palette images anyway, so we don't need to do it explicitly.	 * What to ideally do for truecolor images depends, alas, on the image.	 * gd is intentionally imperfect and doesn't spend a lot of time	 * fussing with such things.	 */		/*  png_set_filter(png_ptr, 0, PNG_FILTER_NONE);  */	/* 2.0.12: this is finally a parameter */	png_set_compression_level(png_ptr, level);	/* can set this to a smaller value without compromising compression if all	 * image data is 16K or less; will save some decoder memory [min == 8] 	 */	/*  png_set_compression_window_bits(png_ptr, 15);  */	if (!im->trueColor) {		if (transparent >= im->colorsTotal || (transparent >= 0 && open[transparent])) {			transparent = -1;		}		for (i = 0; i < gdMaxColors; ++i) {			mapping[i] = -1;		}		/* count actual number of colors used (colorsTotal == high-water mark) */		colors = 0;		for (i = 0; i < im->colorsTotal; ++i) {			if (!open[i]) {				mapping[i] = colors;				++colors;			}		}		if (colors < im->colorsTotal) {			remap = TRUE;		}		if (colors <= 2) {			bit_depth = 1;		} else if (colors <= 4) {			bit_depth = 2;		} else if (colors <= 16) { 			bit_depth = 4;		} else {			bit_depth = 8;		}	}		interlace_type = im->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE;	if (im->trueColor) {		if (im->saveAlphaFlag) {			png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, interlace_type,					PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);		} else {			png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, interlace_type,					PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);		}	} else {		png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_PALETTE, interlace_type,			PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);	}	if (im->trueColor && !im->saveAlphaFlag && (transparent >= 0)) {		/* 2.0.9: fixed by Thomas Winzig */		trans_rgb_value.red = gdTrueColorGetRed (im->transparent);		trans_rgb_value.green = gdTrueColorGetGreen (im->transparent);		trans_rgb_value.blue = gdTrueColorGetBlue (im->transparent);		png_set_tRNS(png_ptr, info_ptr, 0, 0, &trans_rgb_value);	}	if (!im->trueColor) {		/* Oy veh. Remap the PNG palette to put the entries with interesting alpha channel		 * values first. This minimizes the size of the tRNS chunk and thus the size		 * of the PNG file as a whole. 		 */				int tc = 0;		int i;		int j;		int k;		for (i = 0; (i < im->colorsTotal); i++) {			if ((!im->open[i]) && (im->alpha[i] != gdAlphaOpaque)) {				tc++;			}		}		if (tc) {#if 0			for (i = 0; (i < im->colorsTotal); i++) {				trans_values[i] = 255 - ((im->alpha[i] << 1) + (im->alpha[i] >> 6));			}			png_set_tRNS (png_ptr, info_ptr, trans_values, 256, NULL);#endif			if (!remap) {				remap = TRUE;			}			/* (Semi-)transparent indexes come up from the bottom of the list of real colors; opaque			 * indexes come down from the top			 */			j = 0;			k = colors - 1;			for (i = 0; i < im->colorsTotal; i++) {				if (!im->open[i]) {					if (im->alpha[i] != gdAlphaOpaque) {						/* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ 						trans_values[j] = 255 - ((im->alpha[i] << 1) + (im->alpha[i] >> 6));						mapping[i] = j++;					} else {						mapping[i] = k--;					}				}			}			png_set_tRNS(png_ptr, info_ptr, trans_values, tc, NULL);		}	}	/* convert palette to libpng layout */	if (!im->trueColor) {		if (remap) {			for (i = 0; i < im->colorsTotal; ++i) {				if (mapping[i] < 0) {					continue;				}				palette[mapping[i]].red = im->red[i];				palette[mapping[i]].green = im->green[i];				palette[mapping[i]].blue = im->blue[i];			}		} else {			for (i = 0; i < colors; ++i) {				palette[i].red = im->red[i];				palette[i].green = im->green[i];				palette[i].blue = im->blue[i];			}		}		png_set_PLTE(png_ptr, info_ptr, palette, colors);	}	/* write out the PNG header info (everything up to first IDAT) */	png_write_info(png_ptr, info_ptr);	/* make sure < 8-bit images are packed into pixels as tightly as possible */	png_set_packing(png_ptr);	/* This code allocates a set of row buffers and copies the gd image data	 * into them only in the case that remapping is necessary; in gd 1.3 and	 * later, the im->pixels array is laid out identically to libpng's row	 * pointers and can be passed to png_write_image() function directly.	 * The remapping case could be accomplished with less memory for non-	 * interlaced images, but interlacing causes some serious complications.	 */	if (im->trueColor) {		/* performance optimizations by Phong Tran */		int channels = im->saveAlphaFlag ? 4 : 3;		/* Our little 7-bit alpha channel trick costs us a bit here. */		png_bytep *row_pointers;		unsigned char* pOutputRow;		int **ptpixels = im->tpixels;		int *pThisRow;		unsigned char a;		int thisPixel;		png_bytep *prow_pointers;		int saveAlphaFlag = im->saveAlphaFlag;		row_pointers = safe_emalloc(sizeof(png_bytep), height, 0);		prow_pointers = row_pointers;		for (j = 0; j < height; ++j) {			*prow_pointers = (png_bytep) safe_emalloc(width, channels, 0);			pOutputRow = *prow_pointers++;			pThisRow = *ptpixels++;			for (i = 0; i < width; ++i) {				thisPixel = *pThisRow++;				*pOutputRow++ = gdTrueColorGetRed(thisPixel);				*pOutputRow++ = gdTrueColorGetGreen(thisPixel);				*pOutputRow++ = gdTrueColorGetBlue(thisPixel);				if (saveAlphaFlag) {					/* convert the 7-bit alpha channel to an 8-bit alpha channel.					 * We do a little bit-flipping magic, repeating the MSB					 * as the LSB, to ensure that 0 maps to 0 and					 * 127 maps to 255. We also have to invert to match					 * PNG's convention in which 255 is opaque.					 */					a = gdTrueColorGetAlpha(thisPixel);					/* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ 					*pOutputRow++ = 255 - ((a << 1) + (a >> 6));				}			}		}		png_write_image(png_ptr, row_pointers);		png_write_end(png_ptr, info_ptr);		for (j = 0; j < height; ++j) {			gdFree(row_pointers[j]);		}			gdFree(row_pointers);	} else {		if (remap) {			png_bytep *row_pointers;			row_pointers = safe_emalloc(sizeof(png_bytep), height, 0);			for (j = 0; j < height; ++j) {				row_pointers[j] = (png_bytep) gdMalloc(width);				for (i = 0; i < width; ++i) {					row_pointers[j][i] = mapping[im->pixels[j][i]];				}			}			png_write_image(png_ptr, row_pointers);			png_write_end(png_ptr, info_ptr);			for (j = 0; j < height; ++j) {				gdFree(row_pointers[j]);			}			gdFree(row_pointers);		} else {			png_write_image(png_ptr, im->pixels);			png_write_end(png_ptr, info_ptr);		}	}	/* 1.6.3: maybe we should give that memory BACK! TBB */	png_destroy_write_struct(&png_ptr, &info_ptr);}#endif /* HAVE_LIBPNG */

⌨️ 快捷键说明

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