Update Serbian translation from master branch
[wmaker-crm.git] / wrlib / load_webp.c
blobac8ff4f72d4ef59b6ecefd3cb0aec23841fb3722
1 /* load_webp.c - load WEBP image from file
3 * Raster graphics library
5 * Copyright (c) 2014-2021 Window Maker Team
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
20 * MA 02110-1301, USA.
23 #include "config.h"
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <errno.h>
30 #include <webp/decode.h>
32 #include "wraster.h"
33 #include "imgformat.h"
34 #include "wr_i18n.h"
38 * webp_message_from_status
40 * return the text message from a VP8 status code
42 static const char *webp_message_from_status(VP8StatusCode status)
44 static const char *const known_message[] = {
45 /* Known codes as per libWebP 0.4.1 */
46 [VP8_STATUS_OUT_OF_MEMORY] = N_("out of memory"),
47 [VP8_STATUS_INVALID_PARAM] = N_("invalid parameter"),
48 [VP8_STATUS_BITSTREAM_ERROR] = N_("error in the bitstream"),
49 [VP8_STATUS_UNSUPPORTED_FEATURE] = N_("feature is not supported"),
50 [VP8_STATUS_SUSPENDED] = N_("operation suspended"),
51 [VP8_STATUS_USER_ABORT] = N_("aborted by user"),
52 [VP8_STATUS_NOT_ENOUGH_DATA] = N_("not enough data")
54 static char custom_message[128];
56 if (status >= 0 && status < sizeof(known_message) / sizeof(known_message[0]))
57 if (known_message[status] != NULL)
58 return known_message[status];
60 snprintf(custom_message, sizeof(custom_message),
61 _("unknow status code %d"), status);
62 return custom_message;
65 RImage *RLoadWEBP(const char *file_name)
67 FILE *file;
68 RImage *image = NULL;
69 char buffer[20];
70 int raw_data_size;
71 int r;
72 uint8_t *raw_data;
73 VP8StatusCode status;
74 WebPBitstreamFeatures features;
75 uint8_t *ret = NULL;
77 file = fopen(file_name, "rb");
78 if (!file) {
79 RErrorCode = RERR_OPEN;
80 return NULL;
83 if (!fread(buffer, sizeof(buffer), 1, file)) {
84 RErrorCode = RERR_BADIMAGEFILE;
85 fclose(file);
86 return NULL;
89 if (!(buffer[ 0] == 'R' && buffer[ 1] == 'I' && buffer[ 2] == 'F' && buffer[ 3] == 'F' &&
90 buffer[ 8] == 'W' && buffer[ 9] == 'E' && buffer[10] == 'B' && buffer[11] == 'P' &&
91 buffer[12] == 'V' && buffer[13] == 'P' && buffer[14] == '8' &&
92 #if WEBP_DECODER_ABI_VERSION < 0x0003 /* old versions don't support WEBPVP8X and WEBPVP8L */
93 buffer[15] == ' ')) {
94 #else
95 (buffer[15] == ' ' || buffer[15] == 'X' || buffer[15] == 'L'))) {
96 #endif
97 RErrorCode = RERR_BADFORMAT;
98 fclose(file);
99 return NULL;
102 fseek(file, 0L, SEEK_END);
103 raw_data_size = ftell(file);
105 if (raw_data_size <= 0) {
106 fprintf(stderr, _("wrlib: could not get size of WebP file \"%s\", %s\n"),
107 file_name, strerror(errno));
108 RErrorCode = RERR_BADIMAGEFILE;
109 fclose(file);
110 return NULL;
113 raw_data = (uint8_t *) malloc(raw_data_size);
115 if (!raw_data) {
116 RErrorCode = RERR_NOMEMORY;
117 fclose(file);
118 return NULL;
121 fseek(file, 0L, SEEK_SET);
122 r = fread(raw_data, 1, raw_data_size, file);
123 fclose(file);
125 if (r != raw_data_size) {
126 RErrorCode = RERR_READ;
127 free(raw_data);
128 return NULL;
131 status = WebPGetFeatures(raw_data, raw_data_size, &features);
132 if (status != VP8_STATUS_OK) {
133 fprintf(stderr, _("wrlib: could not get features from WebP file \"%s\", %s\n"),
134 file_name, webp_message_from_status(status));
135 RErrorCode = RERR_BADIMAGEFILE;
136 free(raw_data);
137 return NULL;
140 if (features.has_alpha) {
141 image = RCreateImage(features.width, features.height, True);
142 if (!image) {
143 RErrorCode = RERR_NOMEMORY;
144 free(raw_data);
145 return NULL;
147 ret = WebPDecodeRGBAInto(raw_data, raw_data_size, image->data,
148 features.width * features.height * 4,
149 features.width * 4);
150 } else {
151 image = RCreateImage(features.width, features.height, False);
152 if (!image) {
153 RErrorCode = RERR_NOMEMORY;
154 free(raw_data);
155 return NULL;
157 ret = WebPDecodeRGBInto(raw_data, raw_data_size, image->data,
158 features.width * features.height * 3,
159 features.width * 3);
162 free(raw_data);
164 if (!ret) {
165 fprintf(stderr, _("wrlib: failed to decode WebP from file \"%s\"\n"), file_name);
166 RErrorCode = RERR_BADIMAGEFILE;
167 RReleaseImage(image);
168 return NULL;
171 return image;