github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/webp/libwebp/src/webp_api.c (about)

     1  // Copyright 2014 <chaishushan{AT}gmail.com>. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  #include "webp.h"
     6  #include "webp/encode.h"
     7  #include "webp/decode.h"
     8  
     9  #include <stdlib.h>
    10  #include <string.h>
    11  
    12  int webpGetInfo(
    13  	const uint8_t* data, size_t data_size,
    14  	int* width, int* height,
    15  	int* has_alpha
    16  ) {
    17  	WebPBitstreamFeatures features;
    18  	if (WebPGetFeatures(data, data_size, &features) != VP8_STATUS_OK) {
    19  		return 0;
    20  	}
    21  	if (width != NULL) {
    22  		*width  = features.width;
    23  	}
    24  	if (height != NULL) {
    25  		*height = features.height;
    26  	}
    27  	if (has_alpha != NULL) {
    28  		*has_alpha = features.has_alpha;
    29  	}
    30  	return 1;
    31  }
    32  
    33  uint8_t* webpDecodeGray(
    34  	const uint8_t* data, size_t data_size,
    35  	int* width, int* height
    36  ) {
    37  	int w, h;
    38  	uint8_t *y, *u, *v;
    39  	uint8_t *gray, *dst, *src;
    40  	int stride, uv_stride;
    41  	int i;
    42  
    43  	if((y = WebPDecodeYUV(data, data_size, &w, &h, &u, &v, &stride, &uv_stride)) == NULL) {
    44  		return NULL;
    45  	}
    46  	if (width != NULL) {
    47  		*width  = w;
    48  	}
    49  	if (height != NULL) {
    50  		*height = h;
    51  	}
    52  
    53  	if(stride == w) {
    54  		return y;
    55  	}
    56  
    57  	if((gray = (uint8_t*)malloc(w*h)) == NULL) {
    58  		free(y);
    59  		return NULL;
    60  	}
    61  
    62  	src = y;
    63  	dst = gray;
    64  	for(i = 0; i < h; ++i) {
    65  		memmove(dst, src, w);
    66  		src += stride;
    67  		dst += w;
    68  	}
    69  
    70  	free(y);
    71  	return gray;
    72  }
    73  
    74  uint8_t* webpDecodeRGB(
    75  	const uint8_t* data, size_t data_size,
    76  	int* width, int* height
    77  ) {
    78  	return WebPDecodeRGB(data, data_size, width, height);
    79  }
    80  
    81  uint8_t* webpDecodeRGBA(
    82  	const uint8_t* data, size_t data_size,
    83  	int* width, int* height
    84  ) {
    85  	return WebPDecodeRGBA(data, data_size, width, height);
    86  }
    87  
    88  size_t webpEncodeGray(
    89  	const uint8_t* gray, int width, int height, int stride, float quality_factor,
    90  	uint8_t** output
    91  ) {
    92  	size_t output_size;
    93  	uint8_t* rgb;
    94  	int x, y;
    95  
    96  	if((rgb = (uint8_t*)malloc(width*height*3)) == NULL) {
    97  		return 0;
    98  	}
    99  	for(y = 0; y < height; ++y) {
   100  		const uint8_t* src = gray + y*stride;
   101  		uint8_t* dst = rgb + y*width*3;
   102  		for(x = 0; x < width; ++x) {
   103  			uint8_t v = *src++;
   104  			*dst++ = v;
   105  			*dst++ = v;
   106  			*dst++ = v;
   107  		}
   108  	}
   109  
   110  	output_size = WebPEncodeRGB(rgb, width, height, width*3, quality_factor, output);
   111  	free(rgb);
   112  	return output_size;
   113  }
   114  
   115  size_t webpEncodeRGB(
   116  	const uint8_t* rgb, int width, int height, int stride, float quality_factor,
   117  	uint8_t** output
   118  ) {
   119  	return WebPEncodeRGB(rgb, width, height, stride, quality_factor, output);
   120  }
   121  
   122  size_t webpEncodeRGBA(
   123  	const uint8_t* rgba, int width, int height, int stride, float quality_factor,
   124  	uint8_t** output
   125  ) {
   126  	return WebPEncodeRGBA(rgba, width, height, stride, quality_factor, output);
   127  }
   128  
   129  size_t webpEncodeLosslessGray(
   130  	const uint8_t* gray, int width, int height, int stride,
   131  	uint8_t** output
   132  ) {
   133  	size_t output_size;
   134  	uint8_t* rgb;
   135  	int x, y;
   136  
   137  	if((rgb = (uint8_t*)malloc(width*height*3)) == NULL) {
   138  		return 0;
   139  	}
   140  	for(y = 0; y < height; ++y) {
   141  		const uint8_t* src = gray + y*stride;
   142  		uint8_t* dst = rgb + y*width*3;
   143  		for(x = 0; x < width; ++x) {
   144  			uint8_t v = *src++;
   145  			*dst++ = v;
   146  			*dst++ = v;
   147  			*dst++ = v;
   148  		}
   149  	}
   150  
   151  	output_size = WebPEncodeLosslessRGB(rgb, width, height, width*3, output);
   152  	free(rgb);
   153  	return output_size;
   154  }
   155  
   156  size_t webpEncodeLosslessRGB(
   157  	const uint8_t* rgb, int width, int height, int stride,
   158  	uint8_t** output
   159  ) {
   160  	return WebPEncodeLosslessRGB(rgb, width, height, stride, output);
   161  }
   162  
   163  size_t webpEncodeLosslessRGBA(
   164  	const uint8_t* rgba, int width, int height, int stride,
   165  	uint8_t** output
   166  ) {
   167  	return WebPEncodeLosslessRGBA(rgba, width, height, stride, output);
   168  }
   169  
   170  void webpFree(void* p) {
   171  	free(p);
   172  }