1 /* load_webp.c - load WEBP image from file
3 * Raster graphics library
5 * Copyright (c) 2014 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,
30 #include <webp/decode.h>
33 #include "imgformat.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
)
74 WebPBitstreamFeatures features
;
77 file
= fopen(file_name
, "rb");
79 RErrorCode
= RERR_OPEN
;
83 if (!fread(buffer
, sizeof(buffer
), 1, file
)) {
84 RErrorCode
= RERR_BADIMAGEFILE
;
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 */
95 (buffer
[15] == ' ' || buffer
[15] == 'X' || buffer
[15] == 'L'))) {
97 RErrorCode
= RERR_BADFORMAT
;
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
;
113 raw_data
= (uint8_t *) malloc(raw_data_size
);
116 RErrorCode
= RERR_NOMEMORY
;
121 fseek(file
, 0L, SEEK_SET
);
122 r
= fread(raw_data
, 1, raw_data_size
, file
);
125 if (r
!= raw_data_size
) {
126 RErrorCode
= RERR_READ
;
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
;
140 if (features
.has_alpha
) {
141 image
= RCreateImage(features
.width
, features
.height
, True
);
143 RErrorCode
= RERR_NOMEMORY
;
147 ret
= WebPDecodeRGBAInto(raw_data
, raw_data_size
, image
->data
,
148 features
.width
* features
.height
* 4,
151 image
= RCreateImage(features
.width
, features
.height
, False
);
153 RErrorCode
= RERR_NOMEMORY
;
157 ret
= WebPDecodeRGBInto(raw_data
, raw_data_size
, image
->data
,
158 features
.width
* features
.height
* 3,
165 fprintf(stderr
, _("wrlib: failed to decode WebP from file \"%s\"\n"), file_name
);
166 RErrorCode
= RERR_BADIMAGEFILE
;
167 RReleaseImage(image
);