Skip to content

Commit

Permalink
simplify CGO code
Browse files Browse the repository at this point in the history
  • Loading branch information
chai2010 committed Feb 23, 2016
1 parent 2f6c341 commit 6e7100a
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 408 deletions.
330 changes: 2 additions & 328 deletions capi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,332 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "capi.h"
#include "webp/encode.h"
#include "webp/decode.h"
#include "webp/demux.h"
#include "webp/mux.h"
// +build cgo

#include <stdlib.h>
#include <string.h>

int webpGetInfo(
const uint8_t* data, size_t data_size,
int* width, int* height,
int* has_alpha
) {
WebPBitstreamFeatures features;
if (WebPGetFeatures(data, data_size, &features) != VP8_STATUS_OK) {
return 0;
}
if(width != NULL) {
*width = features.width;
}
if(height != NULL) {
*height = features.height;
}
if(has_alpha != NULL) {
*has_alpha = features.has_alpha;
}
return 1;
}

uint8_t* webpDecodeGray(
const uint8_t* data, size_t data_size,
int* width, int* height
) {
int w, h;
uint8_t *y, *u, *v;
uint8_t *gray, *dst, *src;
int stride, uv_stride;
int i;

if((y = WebPDecodeYUV(data, data_size, &w, &h, &u, &v, &stride, &uv_stride)) == NULL) {
return NULL;
}
if (width != NULL) {
*width = w;
}
if (height != NULL) {
*height = h;
}

if(stride == w) {
return y;
}

if((gray = (uint8_t*)malloc(w*h)) == NULL) {
free(y);
return NULL;
}

src = y;
dst = gray;
for(i = 0; i < h; ++i) {
memmove(dst, src, w);
src += stride;
dst += w;
}

free(y);
return gray;
}

uint8_t* webpDecodeRGB(
const uint8_t* data, size_t data_size,
int* width, int* height
) {
return WebPDecodeRGB(data, data_size, width, height);
}

uint8_t* webpDecodeRGBA(
const uint8_t* data, size_t data_size,
int* width, int* height
) {
return WebPDecodeRGBA(data, data_size, width, height);
}

uint8_t* webpEncodeGray(
const uint8_t* gray, int width, int height, int stride, float quality_factor,
size_t* output_size
) {
uint8_t* output;
uint8_t* rgb;
int x, y;

if((rgb = (uint8_t*)malloc(width*height*3)) == NULL) {
return NULL;
}
for(y = 0; y < height; ++y) {
const uint8_t* src = gray + y*stride;
uint8_t* dst = rgb + y*width*3;
for(x = 0; x < width; ++x) {
uint8_t v = *src++;
*dst++ = v;
*dst++ = v;
*dst++ = v;
}
}

*output_size = WebPEncodeRGB(rgb, width, height, width*3, quality_factor, &output);
free(rgb);
return output;
}

uint8_t* webpEncodeRGB(
const uint8_t* rgb, int width, int height, int stride, float quality_factor,
size_t* output_size
) {
uint8_t* output = NULL;
*output_size = WebPEncodeRGB(rgb, width, height, stride, quality_factor, &output);
return output;
}

uint8_t* webpEncodeRGBA(
const uint8_t* rgba, int width, int height, int stride, float quality_factor,
size_t* output_size
) {
uint8_t* output = NULL;
*output_size = WebPEncodeRGBA(rgba, width, height, stride, quality_factor, &output);
return output;
}

uint8_t* webpEncodeLosslessGray(
const uint8_t* gray, int width, int height, int stride,
size_t* output_size
) {
uint8_t* output;
uint8_t* rgb;
int x, y;

if((rgb = (uint8_t*)malloc(width*height*3)) == NULL) {
return 0;
}
for(y = 0; y < height; ++y) {
const uint8_t* src = gray + y*stride;
uint8_t* dst = rgb + y*width*3;
for(x = 0; x < width; ++x) {
uint8_t v = *src++;
*dst++ = v;
*dst++ = v;
*dst++ = v;
}
}

*output_size = WebPEncodeLosslessRGB(rgb, width, height, width*3, &output);
free(rgb);
return output;
}

uint8_t* webpEncodeLosslessRGB(
const uint8_t* rgb, int width, int height, int stride,
size_t* output_size
) {
uint8_t* output = NULL;
*output_size = WebPEncodeLosslessRGB(rgb, width, height, stride, &output);
return output;
}

uint8_t* webpEncodeLosslessRGBA(
const uint8_t* rgba, int width, int height, int stride,
size_t* output_size
) {
uint8_t* output = NULL;
*output_size = WebPEncodeLosslessRGBA(rgba, width, height, stride, &output);
return output;
}

char* webpGetEXIF(const uint8_t* data, size_t data_size, size_t* metadata_size) {
char* metadata = NULL;
WebPData webp_data = {data, data_size};
WebPDemuxer* demux = WebPDemux(&webp_data);
uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
*metadata_size = 0;
if(flags & EXIF_FLAG) {
WebPChunkIterator it;
memset(&it, 0, sizeof(it));
if(WebPDemuxGetChunk(demux, "EXIF", 1, &it)) {
if(it.chunk.bytes != NULL && it.chunk.size > 0) {
metadata = (char*)malloc(it.chunk.size);
memcpy(metadata, it.chunk.bytes, it.chunk.size);
*metadata_size = it.chunk.size;
}
}
WebPDemuxReleaseChunkIterator(&it);
}
WebPDemuxDelete(demux);
return metadata;
}
char* webpGetICCP(const uint8_t* data, size_t data_size, size_t* metadata_size) {
char* metadata = NULL;
WebPData webp_data = {data, data_size};
WebPDemuxer* demux = WebPDemux(&webp_data);
uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
*metadata_size = 0;
if(flags & ICCP_FLAG) {
WebPChunkIterator it;
memset(&it, 0, sizeof(it));
if(WebPDemuxGetChunk(demux, "ICCP", 1, &it)) {
if(it.chunk.bytes != NULL && it.chunk.size > 0) {
metadata = (char*)malloc(it.chunk.size);
memcpy(metadata, it.chunk.bytes, it.chunk.size);
*metadata_size = it.chunk.size;
}
}
WebPDemuxReleaseChunkIterator(&it);
}
WebPDemuxDelete(demux);
return metadata;
}
char* webpGetXMP(const uint8_t* data, size_t data_size, size_t* metadata_size) {
char* metadata = NULL;
WebPData webp_data = {data, data_size};
WebPDemuxer* demux = WebPDemux(&webp_data);
uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS);
*metadata_size = 0;
if(flags & XMP_FLAG) {
WebPChunkIterator it;
memset(&it, 0, sizeof(it));
if(WebPDemuxGetChunk(demux, "XMP ", 1, &it)) {
if(it.chunk.bytes != NULL && it.chunk.size > 0) {
metadata = (char*)malloc(it.chunk.size);
memcpy(metadata, it.chunk.bytes, it.chunk.size);
*metadata_size = it.chunk.size;
}
}
WebPDemuxReleaseChunkIterator(&it);
}
WebPDemuxDelete(demux);
return metadata;
}

uint8_t* webpSetEXIF(
const uint8_t* data, size_t data_size,
const char* metadata, size_t metadata_size,
size_t* new_data_size
) {
WebPData image = {data, data_size};
WebPData profile = {metadata, metadata_size};
WebPData output_data = {NULL, 0};
WebPMux* mux = WebPMuxCreate(&image, 0);
if(WebPMuxSetChunk(mux, "EXIF", &profile, 0) == WEBP_MUX_OK) {
WebPMuxAssemble(mux, &output_data);
}
WebPMuxDelete(mux);
*new_data_size = output_data.size;
return (uint8_t*)(output_data.bytes);
}
uint8_t* webpSetICCP(
const uint8_t* data, size_t data_size,
const char* metadata, size_t metadata_size,
size_t* new_data_size
) {
WebPData image = {data, data_size};
WebPData profile = {metadata, metadata_size};
WebPData output_data = {NULL, 0};
WebPMux* mux = WebPMuxCreate(&image, 0);
if(WebPMuxSetChunk(mux, "ICCP", &profile, 0) == WEBP_MUX_OK) {
WebPMuxAssemble(mux, &output_data);
}
WebPMuxDelete(mux);
*new_data_size = output_data.size;
return (uint8_t*)(output_data.bytes);
}
uint8_t* webpSetXMP(
const uint8_t* data, size_t data_size,
const char* metadata, size_t metadata_size,
size_t* new_data_size
) {
WebPData image = {data, data_size};
WebPData profile = {metadata, metadata_size};
WebPData output_data = {NULL, 0};
WebPMux* mux = WebPMuxCreate(&image, 0);
if(WebPMuxSetChunk(mux, "XMP ", &profile, 0) == WEBP_MUX_OK) {
WebPMuxAssemble(mux, &output_data);
}
WebPMuxDelete(mux);
*new_data_size = output_data.size;
return (uint8_t*)(output_data.bytes);
}

uint8_t* webpDelEXIF(const uint8_t* data, size_t data_size, size_t* new_data_size) {
WebPData image = {data, data_size};
WebPData output_data = {NULL, 0};
WebPMux* mux = WebPMuxCreate(&image, 0);
if(WebPMuxDeleteChunk(mux, "EXIF") == WEBP_MUX_OK) {
WebPMuxAssemble(mux, &output_data);
}
WebPMuxDelete(mux);
*new_data_size = output_data.size;
return (uint8_t*)(output_data.bytes);
}
uint8_t* webpDelICCP(const uint8_t* data, size_t data_size, size_t* new_data_size) {
WebPData image = {data, data_size};
WebPData output_data = {NULL, 0};
WebPMux* mux = WebPMuxCreate(&image, 0);
if(WebPMuxDeleteChunk(mux, "ICCP") == WEBP_MUX_OK) {
WebPMuxAssemble(mux, &output_data);
}
WebPMuxDelete(mux);
*new_data_size = output_data.size;
return (uint8_t*)(output_data.bytes);
}
uint8_t* webpDelXMP(const uint8_t* data, size_t data_size, size_t* new_data_size) {
WebPData image = {data, data_size};
WebPData output_data = {NULL, 0};
WebPMux* mux = WebPMuxCreate(&image, 0);
if(WebPMuxDeleteChunk(mux, "XMP ") == WEBP_MUX_OK) {
WebPMuxAssemble(mux, &output_data);
}
WebPMuxDelete(mux);
*new_data_size = output_data.size;
return (uint8_t*)(output_data.bytes);
}

void* webpMalloc(size_t size) {
return malloc(size);
}

void webpFree(void* p) {
free(p);
}
#include "./internal/libwebp/src/webp.c"
2 changes: 1 addition & 1 deletion capi.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package webp
#cgo CFLAGS: -I./internal/libwebp/include -I./internal/libwebp/src -Wno-pointer-sign -DWEBP_USE_THREAD
#cgo !windows LDFLAGS: -lm
#include "./capi.h"
#include "webp.h"
#include <webp/decode.h>
Expand Down
Loading

0 comments on commit 6e7100a

Please sign in to comment.