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