• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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