1 // Copyright 2015 Google Inc. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the COPYING file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 // -----------------------------------------------------------------------------
9 //
10 // Additional WebP utilities.
11 //
12
13 #include "extras/extras.h"
14 #include "webp/format_constants.h"
15
16 #include <assert.h>
17 #include <string.h>
18
19 #define XTRA_MAJ_VERSION 1
20 #define XTRA_MIN_VERSION 0
21 #define XTRA_REV_VERSION 2
22
23 //------------------------------------------------------------------------------
24
WebPGetExtrasVersion(void)25 int WebPGetExtrasVersion(void) {
26 return (XTRA_MAJ_VERSION << 16) | (XTRA_MIN_VERSION << 8) | XTRA_REV_VERSION;
27 }
28
29 //------------------------------------------------------------------------------
30
WebPImportGray(const uint8_t * gray_data,WebPPicture * pic)31 int WebPImportGray(const uint8_t* gray_data, WebPPicture* pic) {
32 int y, width, uv_width;
33 if (pic == NULL || gray_data == NULL) return 0;
34 pic->colorspace = WEBP_YUV420;
35 if (!WebPPictureAlloc(pic)) return 0;
36 width = pic->width;
37 uv_width = (width + 1) >> 1;
38 for (y = 0; y < pic->height; ++y) {
39 memcpy(pic->y + y * pic->y_stride, gray_data, width);
40 gray_data += width; // <- we could use some 'data_stride' here if needed
41 if ((y & 1) == 0) {
42 memset(pic->u + (y >> 1) * pic->uv_stride, 128, uv_width);
43 memset(pic->v + (y >> 1) * pic->uv_stride, 128, uv_width);
44 }
45 }
46 return 1;
47 }
48
WebPImportRGB565(const uint8_t * rgb565,WebPPicture * pic)49 int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
50 int x, y;
51 uint32_t* dst;
52 if (pic == NULL || rgb565 == NULL) return 0;
53 pic->colorspace = WEBP_YUV420;
54 pic->use_argb = 1;
55 if (!WebPPictureAlloc(pic)) return 0;
56 dst = pic->argb;
57 for (y = 0; y < pic->height; ++y) {
58 const int width = pic->width;
59 for (x = 0; x < width; ++x) {
60 #ifdef WEBP_SWAP_16BIT_CSP
61 const uint32_t rg = rgb565[2 * x + 1];
62 const uint32_t gb = rgb565[2 * x + 0];
63 #else
64 const uint32_t rg = rgb565[2 * x + 0];
65 const uint32_t gb = rgb565[2 * x + 1];
66 #endif
67 uint32_t r = rg & 0xf8;
68 uint32_t g = ((rg << 5) | (gb >> 3)) & 0xfc;
69 uint32_t b = (gb << 5);
70 // dithering
71 r = r | (r >> 5);
72 g = g | (g >> 6);
73 b = b | (b >> 5);
74 dst[x] = (0xffu << 24) | (r << 16) | (g << 8) | b;
75 }
76 rgb565 += 2 * width;
77 dst += pic->argb_stride;
78 }
79 return 1;
80 }
81
WebPImportRGB4444(const uint8_t * rgb4444,WebPPicture * pic)82 int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
83 int x, y;
84 uint32_t* dst;
85 if (pic == NULL || rgb4444 == NULL) return 0;
86 pic->colorspace = WEBP_YUV420;
87 pic->use_argb = 1;
88 if (!WebPPictureAlloc(pic)) return 0;
89 dst = pic->argb;
90 for (y = 0; y < pic->height; ++y) {
91 const int width = pic->width;
92 for (x = 0; x < width; ++x) {
93 #ifdef WEBP_SWAP_16BIT_CSP
94 const uint32_t rg = rgb4444[2 * x + 1];
95 const uint32_t ba = rgb4444[2 * x + 0];
96 #else
97 const uint32_t rg = rgb4444[2 * x + 0];
98 const uint32_t ba = rgb4444[2 * x + 1];
99 #endif
100 uint32_t r = rg & 0xf0;
101 uint32_t g = (rg << 4);
102 uint32_t b = (ba & 0xf0);
103 uint32_t a = (ba << 4);
104 // dithering
105 r = r | (r >> 4);
106 g = g | (g >> 4);
107 b = b | (b >> 4);
108 a = a | (a >> 4);
109 dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
110 }
111 rgb4444 += 2 * width;
112 dst += pic->argb_stride;
113 }
114 return 1;
115 }
116
WebPImportColorMappedARGB(const uint8_t * indexed,int indexed_stride,const uint32_t palette[],int palette_size,WebPPicture * pic)117 int WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
118 const uint32_t palette[], int palette_size,
119 WebPPicture* pic) {
120 int x, y;
121 uint32_t* dst;
122 // 256 as the input buffer is uint8_t.
123 assert(MAX_PALETTE_SIZE <= 256);
124 if (pic == NULL || indexed == NULL || indexed_stride < pic->width ||
125 palette == NULL || palette_size > MAX_PALETTE_SIZE || palette_size <= 0) {
126 return 0;
127 }
128 pic->use_argb = 1;
129 if (!WebPPictureAlloc(pic)) return 0;
130 dst = pic->argb;
131 for (y = 0; y < pic->height; ++y) {
132 for (x = 0; x < pic->width; ++x) {
133 // Make sure we are within the palette.
134 if (indexed[x] >= palette_size) {
135 WebPPictureFree(pic);
136 return 0;
137 }
138 dst[x] = palette[indexed[x]];
139 }
140 indexed += indexed_stride;
141 dst += pic->argb_stride;
142 }
143 return 1;
144 }
145
146 //------------------------------------------------------------------------------
147