mirror of
https://github.com/php/php-src.git
synced 2024-09-22 02:17:32 +00:00
- missing file for webp
This commit is contained in:
parent
dfb96b3b95
commit
12f855b3be
202
ext/gd/libgd/gd_webp.c
Normal file
202
ext/gd/libgd/gd_webp.c
Normal file
@ -0,0 +1,202 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "gd.h"
|
||||
|
||||
|
||||
#ifdef HAVE_LIBVPX
|
||||
#include "webpimg.h"
|
||||
#include "gdhelpers.h"
|
||||
|
||||
extern void gd_YUV420toRGBA(uint8* Y,
|
||||
uint8* U,
|
||||
uint8* V,
|
||||
gdImagePtr im);
|
||||
|
||||
extern void gd_RGBAToYUV420(gdImagePtr im2,
|
||||
uint8* Y,
|
||||
uint8* U,
|
||||
uint8* V);
|
||||
|
||||
const char * gdWebpGetVersionString()
|
||||
{
|
||||
return "not defined";
|
||||
}
|
||||
|
||||
gdImagePtr gdImageCreateFromWebp (FILE * inFile)
|
||||
{
|
||||
gdImagePtr im;
|
||||
gdIOCtx *in = gdNewFileCtx(inFile);
|
||||
im = gdImageCreateFromWebpCtx(in);
|
||||
in->gd_free(in);
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
gdImagePtr gdImageCreateFromWebpPtr (int size, void *data)
|
||||
{
|
||||
int width, height, ret;
|
||||
unsigned char *Y = NULL;
|
||||
unsigned char *U = NULL;
|
||||
unsigned char *V = NULL;
|
||||
gdImagePtr im;
|
||||
|
||||
ret = WebPDecode(data, size, &Y, &U, &V, &width, &height);
|
||||
if (ret != webp_success) {
|
||||
if (Y) free(Y);
|
||||
if (U) free(U);
|
||||
if (V) free(V);
|
||||
php_gd_error("WebP decode: fail to decode input data");
|
||||
return NULL;
|
||||
}
|
||||
im = gdImageCreateTrueColor(width, height);
|
||||
if (!im) {
|
||||
return NULL;
|
||||
}
|
||||
gd_YUV420toRGBA(Y, U, V, im);
|
||||
return im;
|
||||
}
|
||||
|
||||
gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile)
|
||||
{
|
||||
int width, height, ret;
|
||||
unsigned char *filedata;
|
||||
unsigned char dummy[1024];
|
||||
unsigned char *Y = NULL;
|
||||
unsigned char *U = NULL;
|
||||
unsigned char *V = NULL;
|
||||
size_t size = 0, n;
|
||||
gdImagePtr im;
|
||||
|
||||
do {
|
||||
n = gdGetBuf(dummy, 1024, infile);
|
||||
printf("%i\n", n);
|
||||
size += n;
|
||||
} while (n != EOF);
|
||||
|
||||
filedata = gdMalloc(size);
|
||||
if (!filedata) {
|
||||
php_gd_error("WebP decode: alloc failed");
|
||||
return NULL;
|
||||
}
|
||||
gdGetBuf(filedata, size, infile);
|
||||
ret = WebPDecode(filedata, size, &Y, &U, &V, &width, &height);
|
||||
gdFree(filedata);
|
||||
if (ret != webp_success) {
|
||||
if (Y) free(Y);
|
||||
if (U) free(U);
|
||||
if (V) free(V);
|
||||
php_gd_error("WebP decode: fail to decode input data");
|
||||
return NULL;
|
||||
}
|
||||
im = gdImageCreateTrueColor(width, height);
|
||||
gd_YUV420toRGBA(Y, U, V, im);
|
||||
return im;
|
||||
}
|
||||
|
||||
void gdImageWebpEx (gdImagePtr im, FILE * outFile, int quantization)
|
||||
{
|
||||
gdIOCtx *out = gdNewFileCtx(outFile);
|
||||
gdImageWebpCtx(im, out, quantization);
|
||||
out->gd_free(out);
|
||||
}
|
||||
|
||||
void gdImageWebp (gdImagePtr im, FILE * outFile)
|
||||
{
|
||||
gdIOCtx *out = gdNewFileCtx(outFile);
|
||||
gdImageWebpCtx(im, out, -1);
|
||||
out->gd_free(out);
|
||||
}
|
||||
|
||||
void * gdImageWebpPtr (gdImagePtr im, int *size)
|
||||
{
|
||||
void *rv;
|
||||
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
|
||||
gdImageWebpCtx(im, out, -1);
|
||||
rv = gdDPExtractData(out, size);
|
||||
out->gd_free(out);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void * gdImageWebpPtrEx (gdImagePtr im, int *size, int quantization)
|
||||
{
|
||||
void *rv;
|
||||
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
|
||||
gdImageWebpCtx(im, out, quantization);
|
||||
rv = gdDPExtractData(out, size);
|
||||
out->gd_free(out);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Maps normalized QP (quality) to VP8 QP
|
||||
*/
|
||||
int mapQualityToVP8QP(int quality) {
|
||||
#define MIN_QUALITY 0
|
||||
#define MAX_QUALITY 100
|
||||
#define MIN_VP8QP 1
|
||||
#define MAX_VP8QP 63
|
||||
const float scale = MAX_VP8QP - MIN_VP8QP;
|
||||
const float vp8qp =
|
||||
scale * (MAX_QUALITY - quality) / (MAX_QUALITY - MIN_QUALITY) + MIN_VP8QP;
|
||||
if (quality < MIN_QUALITY || quality > MAX_QUALITY) {
|
||||
php_gd_error("Wrong quality value %d.", quality);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)(vp8qp + 0.5);
|
||||
}
|
||||
|
||||
/* 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 gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quantization)
|
||||
{
|
||||
int width = im->sx;
|
||||
int height = im->sy;
|
||||
int colors = im->colorsTotal;
|
||||
int *open = im->open;
|
||||
|
||||
int yuv_width, yuv_height, yuv_nbytes, ret;
|
||||
int vp8_quality;
|
||||
unsigned char *Y = NULL,
|
||||
*U = NULL,
|
||||
*V = NULL;
|
||||
unsigned char *filedata = NULL;
|
||||
|
||||
/* Conversion to Y,U,V buffer */
|
||||
yuv_width = (width + 1) >> 1;
|
||||
yuv_height = (height + 1) >> 1;
|
||||
yuv_nbytes = width * height + 2 * yuv_width * yuv_height;
|
||||
|
||||
if ((Y = (unsigned char *)gdCalloc(yuv_nbytes, sizeof(unsigned char))) == NULL) {
|
||||
php_gd_error("gd-webp error: cannot allocate Y buffer");
|
||||
return;
|
||||
}
|
||||
vp8_quality = mapQualityToVP8QP(quantization);
|
||||
|
||||
U = Y + width * height;
|
||||
V = U + yuv_width * yuv_height;
|
||||
gd_RGBAToYUV420(im, Y, U, V);
|
||||
|
||||
/* Encode Y,U,V and write data to file */
|
||||
ret = WebPEncode(Y, U, V, width, height, width, yuv_width, yuv_height, yuv_width,
|
||||
vp8_quality, &filedata, &yuv_nbytes, NULL);
|
||||
gdFree(Y);
|
||||
|
||||
if (ret != webp_success) {
|
||||
if (filedata) {
|
||||
free(filedata);
|
||||
}
|
||||
php_gd_error("gd-webp error: WebP Encoder failed");
|
||||
return;
|
||||
}
|
||||
|
||||
gdPutBuf (filedata, yuv_nbytes, outfile);
|
||||
free(filedata);
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBVPX */
|
Loading…
Reference in New Issue
Block a user