webp.c (2333B)
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20#include "config.h" 21#include "log.h" 22#include "webp.h" 23 24#include <cairo/cairo.h> 25#include <guacamole/client.h> 26#include <webp/decode.h> 27 28#include <stdint.h> 29#include <stdlib.h> 30 31cairo_surface_t* guacenc_webp_decoder(unsigned char* data, int length) { 32 33 int width, height; 34 35 /* Validate WebP and pull dimensions */ 36 if (!WebPGetInfo((uint8_t*) data, length, &width, &height)) { 37 guacenc_log(GUAC_LOG_WARNING, "Invalid WebP data"); 38 return NULL; 39 } 40 41 /* Create blank Cairo surface */ 42 cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 43 width, height); 44 45 /* Fill surface with opaque black */ 46 cairo_t* cairo = cairo_create(surface); 47 cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); 48 cairo_set_source_rgba(cairo, 0.0, 0.0, 0.0, 1.0); 49 cairo_paint(cairo); 50 cairo_destroy(cairo); 51 52 /* Finish any pending draws */ 53 cairo_surface_flush(surface); 54 55 /* Pull underlying buffer and its stride */ 56 int stride = cairo_image_surface_get_stride(surface); 57 unsigned char* image = cairo_image_surface_get_data(surface); 58 59 /* Read WebP into surface */ 60 uint8_t* result = WebPDecodeBGRAInto((uint8_t*) data, length, 61 (uint8_t*) image, stride * height, stride); 62 63 /* Verify WebP was successfully decoded */ 64 if (result == NULL) { 65 guacenc_log(GUAC_LOG_WARNING, "Invalid WebP data"); 66 cairo_surface_destroy(surface); 67 return NULL; 68 } 69 70 /* WebP was read successfully */ 71 return surface; 72 73} 74