Created
May 27, 2024 09:10
-
-
Save crispy-computing-machine/0d9e51c05024c07260f58028991ca748 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -bur gd.c gd.c | |
--- gd.c 2024-04-10 10:19:28.000000000 -0400 | |
+++ gd.c 2024-04-19 08:41:01.205119300 -0400 | |
@@ -129,6 +129,13 @@ | |
/* output streaming (formerly gd_ctx.c) */ | |
static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn); | |
+ | |
+/* Functions for BITMAP 24bits */ | |
+static inline unsigned char *_gdex_write_uint16le(unsigned char *ptr, uint16_t n); | |
+static inline unsigned char *_gdex_write_int32le(unsigned char *ptr, int32_t n); | |
+static inline unsigned char *_gdex_write_uint32le(unsigned char *ptr, uint32_t n); | |
+static unsigned char *_gdex_gdimage_to_bmp24(gdImagePtr im, size_t *size); | |
+ | |
/********************************************************* | |
* | |
* GD Object Representation | |
@@ -634,6 +641,7 @@ | |
} | |
/* }}} */ | |
+ | |
/* {{{ Set the line drawing styles for use with imageline and IMG_COLOR_STYLED. */ | |
PHP_FUNCTION(imagesetstyle) | |
{ | |
@@ -3955,6 +3963,134 @@ | |
/* }}} */ | |
+/* {{{ Get BITMAP 24bit matrix. */ | |
+PHP_FUNCTION(imagegetbitmap24) | |
+{ | |
+ zval *im_zval; | |
+ gdImagePtr im; | |
+ gdImagePtr imtmp = NULL; | |
+ unsigned char *buffer = NULL; | |
+ size_t buffer_size, written_size; | |
+ int x1, y1, x2, y2; | |
+ | |
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &im_zval, gd_image_ce) == FAILURE) { | |
+ RETURN_THROWS(); | |
+ } | |
+ | |
+ im = php_gd_libgdimageptr_from_zval_p(im_zval); | |
+ | |
+ if (!gdImageTrueColor(im)) { | |
+ imtmp = gdImageCreateTrueColor(gdImageSX(im),gdImageSY(im)); | |
+ gdImageCopyResampled(imtmp,im,0,0,0,0,gdImageSX(im),gdImageSY(im),gdImageSX(im),gdImageSY(im)); | |
+ buffer = _gdex_gdimage_to_bmp24(imtmp, &buffer_size); | |
+ gdImageDestroy(imtmp); | |
+ } else { | |
+ buffer = _gdex_gdimage_to_bmp24(im, &buffer_size); | |
+ } | |
+ if (buffer == NULL) { | |
+ RETURN_BOOL(0); | |
+ } | |
+ | |
+ RETURN_STRINGL(buffer,buffer_size,1); | |
+ efree(buffer); | |
+} | |
+/* }}} */ | |
+ | |
+ | |
+ | |
+ | |
+static inline unsigned char *_gdex_write_uint16le(unsigned char *ptr, uint16_t n) { | |
+ *ptr++ = (unsigned char)(0xff & n); | |
+ *ptr++ = (unsigned char)(0xff & (n >> 8)); | |
+ return ptr; | |
+} | |
+ | |
+static inline unsigned char *_gdex_write_int32le(unsigned char *ptr, int32_t n) { | |
+ *ptr++ = (unsigned char)(0xff & n); | |
+ *ptr++ = (unsigned char)(0xff & (n >> 8)); | |
+ *ptr++ = (unsigned char)(0xff & (n >> 16)); | |
+ *ptr++ = (unsigned char)(0xff & (n >> 24)); | |
+ return ptr; | |
+} | |
+ | |
+static inline unsigned char *_gdex_write_uint32le(unsigned char *ptr, uint32_t n) { | |
+ *ptr++ = (unsigned char)(0xff & n); | |
+ *ptr++ = (unsigned char)(0xff & (n >> 8)); | |
+ *ptr++ = (unsigned char)(0xff & (n >> 16)); | |
+ *ptr++ = (unsigned char)(0xff & (n >> 24)); | |
+ return ptr; | |
+} | |
+ | |
+ | |
+ | |
+static unsigned char *_gdex_gdimage_to_bmp24(gdImagePtr im, size_t *size) { | |
+ unsigned char *buffer, *ptr; | |
+ size_t buffer_size, image_offset, image_size, line_size; | |
+ int x, y, width, height; | |
+ | |
+ /* get image size */ | |
+ width = gdImageSX(im); | |
+ height = gdImageSY(im); | |
+ | |
+ /* calculate required memory size */ | |
+ image_offset = 14 + 40; | |
+ line_size = ((size_t)width * 24 + 31) / 32 * 4; | |
+ image_size = line_size * (size_t)height; | |
+ buffer_size = image_offset + image_size; | |
+ | |
+ /* allocate */ | |
+ buffer = (unsigned char *)emalloc(buffer_size); | |
+ if (buffer == NULL) { | |
+ php_error_docref(NULL, E_WARNING, | |
+ "Failed to allocate memory for %zu bytes", buffer_size); | |
+ return NULL; | |
+ } | |
+ ptr = buffer; | |
+ | |
+ /* write BITMAPFILEHEADER */ | |
+ *ptr++ = 'B'; /* bfType */ | |
+ *ptr++ = 'M'; /* bfType */ | |
+ ptr = _gdex_write_uint32le(ptr, (uint32_t)buffer_size); /* bfSize */ | |
+ ptr = _gdex_write_uint16le(ptr, 0); /* bfReserved1 */ | |
+ ptr = _gdex_write_uint16le(ptr, 0); /* bfReserved2 */ | |
+ ptr = _gdex_write_uint32le(ptr, (uint32_t)image_offset); /* bfOffBits */ | |
+ | |
+ /* write BITMAPINFOHEADER */ | |
+ ptr = _gdex_write_uint32le(ptr, 40); /* biSize */ | |
+ ptr = _gdex_write_int32le(ptr, (int32_t)width); /* biWidth */ | |
+ ptr = _gdex_write_int32le(ptr, (int32_t)height); /* biHeight */ | |
+ ptr = _gdex_write_uint16le(ptr, 1); /* biPlanes */ | |
+ ptr = _gdex_write_uint16le(ptr, 24); /* biBitCount: 24bpp */ | |
+ ptr = _gdex_write_uint32le(ptr, 0); /* biCopmression: BI_RGB */ | |
+ ptr = _gdex_write_uint32le(ptr, (uint32_t)image_size); /* biSizeImage */ | |
+ ptr = _gdex_write_int32le(ptr, 3780); /* biXPixPerMeter: 96dpi */ | |
+ ptr = _gdex_write_int32le(ptr, 3780); /* biYPixPerMeter: 96dpi */ | |
+ ptr = _gdex_write_uint32le(ptr, 0); /* biClrUsed */ | |
+ ptr = _gdex_write_uint32le(ptr, 0); /* biCirImportant */ | |
+ | |
+ /* write image data */ | |
+ y = height; | |
+ while (y > 0) { | |
+ unsigned char *eol = ptr + line_size; | |
+ --y; | |
+ for (x = 0; x < width; x++) { | |
+ int tpixel = gdImageTrueColorPixel(im, x, y); | |
+ *ptr++ = (unsigned char)(0xff & gdTrueColorGetBlue(tpixel)); | |
+ *ptr++ = (unsigned char)(0xff & gdTrueColorGetGreen(tpixel)); | |
+ *ptr++ = (unsigned char)(0xff & gdTrueColorGetRed(tpixel)); | |
+ } | |
+ while (ptr < eol) { | |
+ *ptr++ = '\0'; | |
+ } | |
+ } | |
+ | |
+ if (size != NULL) { | |
+ *size = buffer_size; | |
+ } | |
+ return buffer; | |
+} | |
+ | |
+ | |
/********************************************************* | |
* | |
* Stream Handling | |
diff -bur gd_arginfo.h gd_arginfo.h | |
--- gd_arginfo.h 2024-04-10 10:19:28.000000000 -0400 | |
+++ gd_arginfo.h 2024-04-19 08:44:41.264103900 -0400 | |
@@ -576,6 +576,12 @@ | |
ZEND_END_ARG_INFO() | |
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagegetbitmap24, 0, 1, IS_STRING, 0) | |
+ ZEND_ARG_OBJ_INFO(0, image, GdImage, 0) | |
+ZEND_END_ARG_INFO() | |
+ | |
+ | |
+ | |
ZEND_FUNCTION(gd_info); | |
ZEND_FUNCTION(imageloadfont); | |
ZEND_FUNCTION(imagesetstyle); | |
@@ -715,6 +721,10 @@ | |
ZEND_FUNCTION(imagesetinterpolation); | |
ZEND_FUNCTION(imageresolution); | |
+ZEND_FUNCTION(imagegetbitmap24); | |
+ | |
+ | |
+ | |
static const zend_function_entry ext_functions[] = { | |
ZEND_FE(gd_info, arginfo_gd_info) | |
@@ -861,6 +871,10 @@ | |
ZEND_FE(imagegetinterpolation, arginfo_imagegetinterpolation) | |
ZEND_FE(imagesetinterpolation, arginfo_imagesetinterpolation) | |
ZEND_FE(imageresolution, arginfo_imageresolution) | |
+ | |
+ ZEND_FE(imagegetbitmap24, arginfo_imagegetbitmap24) | |
+ | |
+ | |
ZEND_FE_END | |
}; | |
@@ -957,6 +971,9 @@ | |
REGISTER_LONG_CONSTANT("IMG_FILTER_SMOOTH", IMAGE_FILTER_SMOOTH, CONST_PERSISTENT); | |
REGISTER_LONG_CONSTANT("IMG_FILTER_PIXELATE", IMAGE_FILTER_PIXELATE, CONST_PERSISTENT); | |
REGISTER_LONG_CONSTANT("IMG_FILTER_SCATTER", IMAGE_FILTER_SCATTER, CONST_PERSISTENT); | |
+ REGISTER_LONG_CONSTANT("GD_BITMAP24_HEADER", 14, CONST_PERSISTENT); | |
+ REGISTER_LONG_CONSTANT("GD_BITMAP24_BITS", 54, CONST_PERSISTENT); | |
+ | |
#if defined(GD_VERSION_STRING) | |
REGISTER_STRING_CONSTANT("GD_VERSION", GD_VERSION_STRING, CONST_PERSISTENT); | |
#endif | |
Only in ext\gd: test.patch |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment