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 #include "src/dsp/dsp.h"
16
17 #include <assert.h>
18 #include <string.h>
19
20 #define XTRA_MAJ_VERSION 1
21 #define XTRA_MIN_VERSION 3
22 #define XTRA_REV_VERSION 0
23
24 //------------------------------------------------------------------------------
25
WebPGetExtrasVersion(void)26 int WebPGetExtrasVersion(void) {
27 return (XTRA_MAJ_VERSION << 16) | (XTRA_MIN_VERSION << 8) | XTRA_REV_VERSION;
28 }
29
30 //------------------------------------------------------------------------------
31
WebPImportGray(const uint8_t * gray_data,WebPPicture * pic)32 int WebPImportGray(const uint8_t* gray_data, WebPPicture* pic) {
33 int y, width, uv_width;
34 if (pic == NULL || gray_data == NULL) return 0;
35 pic->colorspace = WEBP_YUV420;
36 if (!WebPPictureAlloc(pic)) return 0;
37 width = pic->width;
38 uv_width = (width + 1) >> 1;
39 for (y = 0; y < pic->height; ++y) {
40 memcpy(pic->y + y * pic->y_stride, gray_data, width);
41 gray_data += width; // <- we could use some 'data_stride' here if needed
42 if ((y & 1) == 0) {
43 memset(pic->u + (y >> 1) * pic->uv_stride, 128, uv_width);
44 memset(pic->v + (y >> 1) * pic->uv_stride, 128, uv_width);
45 }
46 }
47 return 1;
48 }
49
WebPImportRGB565(const uint8_t * rgb565,WebPPicture * pic)50 int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
51 int x, y;
52 uint32_t* dst;
53 if (pic == NULL || rgb565 == NULL) return 0;
54 pic->colorspace = WEBP_YUV420;
55 pic->use_argb = 1;
56 if (!WebPPictureAlloc(pic)) return 0;
57 dst = pic->argb;
58 for (y = 0; y < pic->height; ++y) {
59 const int width = pic->width;
60 for (x = 0; x < width; ++x) {
61 #if defined(WEBP_SWAP_16BIT_CSP) && (WEBP_SWAP_16BIT_CSP == 1)
62 const uint32_t rg = rgb565[2 * x + 1];
63 const uint32_t gb = rgb565[2 * x + 0];
64 #else
65 const uint32_t rg = rgb565[2 * x + 0];
66 const uint32_t gb = rgb565[2 * x + 1];
67 #endif
68 uint32_t r = rg & 0xf8;
69 uint32_t g = ((rg << 5) | (gb >> 3)) & 0xfc;
70 uint32_t b = (gb << 5);
71 // dithering
72 r = r | (r >> 5);
73 g = g | (g >> 6);
74 b = b | (b >> 5);
75 dst[x] = (0xffu << 24) | (r << 16) | (g << 8) | b;
76 }
77 rgb565 += 2 * width;
78 dst += pic->argb_stride;
79 }
80 return 1;
81 }
82
WebPImportRGB4444(const uint8_t * rgb4444,WebPPicture * pic)83 int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
84 int x, y;
85 uint32_t* dst;
86 if (pic == NULL || rgb4444 == NULL) return 0;
87 pic->colorspace = WEBP_YUV420;
88 pic->use_argb = 1;
89 if (!WebPPictureAlloc(pic)) return 0;
90 dst = pic->argb;
91 for (y = 0; y < pic->height; ++y) {
92 const int width = pic->width;
93 for (x = 0; x < width; ++x) {
94 #if defined(WEBP_SWAP_16BIT_CSP) && (WEBP_SWAP_16BIT_CSP == 1)
95 const uint32_t rg = rgb4444[2 * x + 1];
96 const uint32_t ba = rgb4444[2 * x + 0];
97 #else
98 const uint32_t rg = rgb4444[2 * x + 0];
99 const uint32_t ba = rgb4444[2 * x + 1];
100 #endif
101 uint32_t r = rg & 0xf0;
102 uint32_t g = (rg << 4);
103 uint32_t b = (ba & 0xf0);
104 uint32_t a = (ba << 4);
105 // dithering
106 r = r | (r >> 4);
107 g = g | (g >> 4);
108 b = b | (b >> 4);
109 a = a | (a >> 4);
110 dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
111 }
112 rgb4444 += 2 * width;
113 dst += pic->argb_stride;
114 }
115 return 1;
116 }
117
WebPImportColorMappedARGB(const uint8_t * indexed,int indexed_stride,const uint32_t palette[],int palette_size,WebPPicture * pic)118 int WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
119 const uint32_t palette[], int palette_size,
120 WebPPicture* pic) {
121 int x, y;
122 uint32_t* dst;
123 // 256 as the input buffer is uint8_t.
124 assert(MAX_PALETTE_SIZE <= 256);
125 if (pic == NULL || indexed == NULL || indexed_stride < pic->width ||
126 palette == NULL || palette_size > MAX_PALETTE_SIZE || palette_size <= 0) {
127 return 0;
128 }
129 pic->use_argb = 1;
130 if (!WebPPictureAlloc(pic)) return 0;
131 dst = pic->argb;
132 for (y = 0; y < pic->height; ++y) {
133 for (x = 0; x < pic->width; ++x) {
134 // Make sure we are within the palette.
135 if (indexed[x] >= palette_size) {
136 WebPPictureFree(pic);
137 return 0;
138 }
139 dst[x] = palette[indexed[x]];
140 }
141 indexed += indexed_stride;
142 dst += pic->argb_stride;
143 }
144 return 1;
145 }
146
147 //------------------------------------------------------------------------------
148
WebPUnmultiplyARGB(WebPPicture * pic)149 int WebPUnmultiplyARGB(WebPPicture* pic) {
150 int y;
151 uint32_t* dst;
152 if (pic == NULL || pic->use_argb != 1 || pic->argb == NULL) return 0;
153 WebPInitAlphaProcessing();
154 dst = pic->argb;
155 for (y = 0; y < pic->height; ++y) {
156 WebPMultARGBRow(dst, pic->width, /*inverse=*/1);
157 dst += pic->argb_stride;
158 }
159 return 1;
160 }
161
162 //------------------------------------------------------------------------------
163