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

📄 gd_gd2.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	int scx, scy, ecx, ecy, fsx, fsy;	int nc, ncx, ncy, cs, cx, cy;	int x, y, ylo, yhi, xlo, xhi;	int dstart, dpos;	int i;	/* 2.0.12: unsigned is correct; fixes problems with color munging. Thanks to Steven Brown. */	unsigned int ch;	int vers, fmt;	t_chunk_info *chunkIdx = NULL;	unsigned char *chunkBuf = NULL;	int chunkNum;	int chunkMax = 0;	uLongf chunkLen;	int chunkPos = 0;	int compMax;	char *compBuf = NULL;	gdImagePtr im;	/* The next few lines are basically copied from gd2CreateFromFile	 * we change the file size, so don't want to use the code directly.	 * but we do need to know the file size.	 */	if (_gd2GetHeader(in, &fsx, &fsy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx) != 1) {		goto fail1;	}	GD2_DBG(php_gd_error("File size is %dx%d\n", fsx, fsy));	/* This is the difference - make a file based on size of chunks. */	if (gd2_truecolor(fmt)) {		im = gdImageCreateTrueColor(w, h);	} else {		im = gdImageCreate(w, h);	}	if (im == NULL) {		goto fail1;	}	if (!_gdGetColors(in, im, vers == 2)) {		goto fail2;	}	GD2_DBG(php_gd_error("Image palette completed: %d colours\n", im->colorsTotal));	/* Process the header info */	nc = ncx * ncy;	if (gd2_compressed(fmt)) {		/* Find the maximum compressed chunk size. */		compMax = 0;		for (i = 0; (i < nc); i++) {			if (chunkIdx[i].size > compMax) {				compMax = chunkIdx[i].size;			}		}		compMax++;		if (im->trueColor) {			chunkMax = cs * cs * 4;		} else {			chunkMax = cs * cs;		}		if (chunkMax <= 0) {			goto fail2;		}				chunkBuf = gdCalloc(chunkMax, 1);		compBuf = gdCalloc(compMax, 1);	}	/* Work out start/end chunks */	scx = srcx / cs;	scy = srcy / cs;	if (scx < 0) {		scx = 0;	}	if (scy < 0) {		scy = 0;	}	ecx = (srcx + w) / cs;	ecy = (srcy + h) / cs;	if (ecx >= ncx) {		ecx = ncx - 1;	}	if (ecy >= ncy) {		ecy = ncy - 1;	}	/* Remember file position of image data. */	dstart = gdTell(in);	GD2_DBG(php_gd_error("Data starts at %d\n", dstart));	/* Loop through the chunks. */	for (cy = scy; (cy <= ecy); cy++) {		ylo = cy * cs;		yhi = ylo + cs;		if (yhi > fsy) {			yhi = fsy;		}		for (cx = scx; cx <= ecx; cx++) {			xlo = cx * cs;			xhi = xlo + cs;			if (xhi > fsx) {				xhi = fsx;			}			GD2_DBG(php_gd_error("Processing Chunk (%d, %d), from %d to %d\n", cx, cy, ylo, yhi));			if (!gd2_compressed(fmt)) {				GD2_DBG(php_gd_error("Using raw format data\n"));				if (im->trueColor) {					dpos = (cy * (cs * fsx) * 4 + cx * cs * (yhi - ylo) * 4) + dstart;				} else {					dpos = cy * (cs * fsx) + cx * cs * (yhi - ylo) + dstart;				}				/* gd 2.0.11: gdSeek returns TRUE on success, not 0. Longstanding bug. 01/16/03 */				if (!gdSeek(in, dpos)) {					php_gd_error_ex(E_WARNING, "Error from seek: %d\n", errno);					goto fail2;				}				GD2_DBG(php_gd_error("Reading (%d, %d) from position %d\n", cx, cy, dpos - dstart));			} else {				chunkNum = cx + cy * ncx;				chunkLen = chunkMax;				if (!_gd2ReadChunk (chunkIdx[chunkNum].offset, compBuf, chunkIdx[chunkNum].size, chunkBuf, &chunkLen, in)) {					php_gd_error("Error reading comproessed chunk\n");					goto fail2;				}				chunkPos = 0;				GD2_DBG(php_gd_error("Reading (%d, %d) from chunk %d\n", cx, cy, chunkNum));			}			GD2_DBG(php_gd_error("   into (%d, %d) - (%d, %d)\n", xlo, ylo, xhi, yhi));			for (y = ylo; (y < yhi); y++) {				for (x = xlo; x < xhi; x++) {					if (!gd2_compressed(fmt)) {						if (im->trueColor) {							if (!gdGetInt(&ch, in)) {								ch = 0;							}						} else {							ch = gdGetC(in);							if ((int)ch == EOF) {								ch = 0;							}						}					} else {						if (im->trueColor) {							ch = chunkBuf[chunkPos++];							ch = (ch << 8) + chunkBuf[chunkPos++];							ch = (ch << 8) + chunkBuf[chunkPos++];							ch = (ch << 8) + chunkBuf[chunkPos++];						} else {							ch = chunkBuf[chunkPos++];						}					}					/* Only use a point that is in the image. */					if ((x >= srcx) && (x < (srcx + w)) && (x < fsx) && (x >= 0) && (y >= srcy) && (y < (srcy + h)) && (y < fsy) && (y >= 0)) {						if (im->trueColor) {  							im->tpixels[y - srcy][x - srcx] = ch;						} else {							im->pixels[y - srcy][x - srcx] = ch;						}   					}				}			}		}	}	if (chunkBuf) {		gdFree(chunkBuf);	}	if (compBuf) {		gdFree(compBuf);	}	if (chunkIdx) {		gdFree(chunkIdx);	}		return im;fail2:	gdImageDestroy(im);fail1:	if (chunkBuf) {		gdFree(chunkBuf);	}	if (compBuf) {		gdFree(compBuf);	}	if (chunkIdx) {		gdFree(chunkIdx);	}	return 0;}static void _gd2PutHeader (gdImagePtr im, gdIOCtx * out, int cs, int fmt, int cx, int cy){	int i;	/* Send the gd2 id, to verify file format. */	for (i = 0; i < 4; i++) {		gdPutC((unsigned char) (GD2_ID[i]), out);	}	/* We put the version info first, so future versions can easily change header info. */	gdPutWord(GD2_VERS, out);	gdPutWord(im->sx, out);	gdPutWord(im->sy, out);	gdPutWord(cs, out);	gdPutWord(fmt, out);	gdPutWord(cx, out);	gdPutWord(cy, out);}static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt){	int ncx, ncy, cx, cy;	int x, y, ylo, yhi, xlo, xhi;	int chunkLen;	int chunkNum = 0;	char *chunkData = NULL;	/* So we can gdFree it with impunity. */	char *compData = NULL;	/* So we can gdFree it with impunity. */	uLongf compLen;	int idxPos = 0;	int idxSize;	t_chunk_info *chunkIdx = NULL; /* So we can gdFree it with impunity. */	int posSave;	int bytesPerPixel = im->trueColor ? 4 : 1;	int compMax = 0;	/* Force fmt to a valid value since we don't return anything. */	if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)) { 			fmt = im->trueColor ? GD2_FMT_TRUECOLOR_COMPRESSED : GD2_FMT_COMPRESSED;	}	if (im->trueColor) {		fmt += 2;	}	/* Make sure chunk size is valid. These are arbitrary values; 64 because it seems	 * a little silly to expect performance improvements on a 64x64 bit scale, and	 * 4096 because we buffer one chunk, and a 16MB buffer seems a little large - it may be	 * OK for one user, but for another to read it, they require the buffer.	 */	if (cs == 0) {		cs = GD2_CHUNKSIZE;	} else if (cs < GD2_CHUNKSIZE_MIN) {		cs = GD2_CHUNKSIZE_MIN;	} else if (cs > GD2_CHUNKSIZE_MAX) {		cs = GD2_CHUNKSIZE_MAX;	}	/* Work out number of chunks. */	ncx = im->sx / cs + 1;	ncy = im->sy / cs + 1;	/* Write the standard header. */	_gd2PutHeader (im, out, cs, fmt, ncx, ncy);	if (gd2_compressed(fmt)) {		/* Work out size of buffer for compressed data, If CHUNKSIZE is large,	 	 * then these will be large!	 	 */		/* The zlib notes say output buffer size should be (input size) * 1.01 * 12		 * - we'll use 1.02 to be paranoid.		 */		compMax = (int)(cs * bytesPerPixel * cs * 1.02f) + 12;		/* Allocate the buffers.  */		chunkData = safe_emalloc(cs * bytesPerPixel, cs, 0);		memset(chunkData, 0, cs * bytesPerPixel * cs);		if (compMax <= 0) {			goto fail;				}		compData = gdCalloc(compMax, 1);		/* Save the file position of chunk index, and allocate enough space for		 * each chunk_info block . 		 */		idxPos = gdTell(out);		idxSize = ncx * ncy * sizeof(t_chunk_info);		GD2_DBG(php_gd_error("Index size is %d\n", idxSize));		gdSeek(out, idxPos + idxSize);		chunkIdx = safe_emalloc(idxSize, sizeof(t_chunk_info), 0);		memset(chunkIdx, 0, idxSize * sizeof(t_chunk_info));	}	_gdPutColors (im, out);	GD2_DBG(php_gd_error("Size: %dx%d\n", im->sx, im->sy));	GD2_DBG(php_gd_error("Chunks: %dx%d\n", ncx, ncy));	for (cy = 0; (cy < ncy); cy++) {		for (cx = 0; (cx < ncx); cx++) {			ylo = cy * cs;			yhi = ylo + cs;			if (yhi > im->sy) {				yhi = im->sy;			}			GD2_DBG(php_gd_error("Processing Chunk (%dx%d), y from %d to %d\n", cx, cy, ylo, yhi));			chunkLen = 0;			for (y = ylo; (y < yhi); y++) {				GD2_DBG(php_gd_error("y=%d: ",y));				xlo = cx * cs;				xhi = xlo + cs;				if (xhi > im->sx) {					xhi = im->sx;				}				if (gd2_compressed(fmt)) {					for (x = xlo; x < xhi; x++) {						GD2_DBG(php_gd_error("%d...",x));						if (im->trueColor) {							int p = im->tpixels[y][x];							chunkData[chunkLen++] = gdTrueColorGetAlpha(p);							chunkData[chunkLen++] = gdTrueColorGetRed(p);							chunkData[chunkLen++] = gdTrueColorGetGreen(p);							chunkData[chunkLen++] = gdTrueColorGetBlue(p);						} else {							chunkData[chunkLen++] = im->pixels[y][x];						}					}				} else {					for (x = xlo; x < xhi; x++) {						GD2_DBG(php_gd_error("%d, ",x)); 						if (im->trueColor) {							gdPutInt(im->tpixels[y][x], out);						} else {							gdPutC((unsigned char) im->pixels[y][x], out);						}					}				}				GD2_DBG(php_gd_error("y=%d done.\n",y)); 			}			if (gd2_compressed(fmt)) {				compLen = compMax;				if (compress((unsigned char *) &compData[0], &compLen, (unsigned char *) &chunkData[0], chunkLen) != Z_OK) {					php_gd_error("Error from compressing\n");				} else {					chunkIdx[chunkNum].offset = gdTell(out);					chunkIdx[chunkNum++].size = compLen;					GD2_DBG(php_gd_error("Chunk %d size %d offset %d\n", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset));					if (gdPutBuf (compData, compLen, out) <= 0) {						/* Any alternate suggestions for handling this? */						php_gd_error_ex(E_WARNING, "Error %d on write\n", errno);					}				}			}		}    	}	if (gd2_compressed(fmt)) {		/* Save the position, write the index, restore position (paranoia). */		GD2_DBG(php_gd_error("Seeking %d to write index\n", idxPos));		posSave = gdTell(out);		gdSeek(out, idxPos);		GD2_DBG(php_gd_error("Writing index\n"));		for (x = 0; x < chunkNum; x++) {			GD2_DBG(php_gd_error("Chunk %d size %d offset %d\n", x, chunkIdx[x].size, chunkIdx[x].offset));			gdPutInt(chunkIdx[x].offset, out);			gdPutInt(chunkIdx[x].size, out);		}		gdSeek(out, posSave);	}fail:	GD2_DBG(php_gd_error("Freeing memory\n"));	if (chunkData) {		gdFree(chunkData);	}	if (compData) { 		gdFree(compData);	}	if (chunkIdx) {		gdFree(chunkIdx);	}	GD2_DBG(php_gd_error("Done\n"));}void gdImageGd2 (gdImagePtr im, FILE * outFile, int cs, int fmt){	gdIOCtx *out = gdNewFileCtx(outFile);	_gdImageGd2(im, out, cs, fmt);		out->gd_free(out);}void *gdImageGd2Ptr (gdImagePtr im, int cs, int fmt, int *size){	void *rv;	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);	_gdImageGd2(im, out, cs, fmt);	rv = gdDPExtractData(out, size);	out->gd_free(out);		return rv;}

⌨️ 快捷键说明

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