Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(652)

Side by Side Diff: third_party/libwebp/enc/near_lossless.c

Issue 2149863002: libwebp: update to v0.5.1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/libwebp/enc/histogram.c ('k') | third_party/libwebp/enc/picture.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 Google Inc. All Rights Reserved. 1 // Copyright 2014 Google Inc. All Rights Reserved.
2 // 2 //
3 // Use of this source code is governed by a BSD-style license 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 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 5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may 6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree. 7 // be found in the AUTHORS file in the root of the source tree.
8 // ----------------------------------------------------------------------------- 8 // -----------------------------------------------------------------------------
9 // 9 //
10 // Near-lossless image preprocessing adjusts pixel values to help 10 // Near-lossless image preprocessing adjusts pixel values to help
11 // compressibility with a guarantee of maximum deviation between original and 11 // compressibility with a guarantee of maximum deviation between original and
12 // resulting pixel values. 12 // resulting pixel values.
13 // 13 //
14 // Author: Jyrki Alakuijala (jyrki@google.com) 14 // Author: Jyrki Alakuijala (jyrki@google.com)
15 // Converted to C by Aleksander Kramarz (akramarz@google.com) 15 // Converted to C by Aleksander Kramarz (akramarz@google.com)
16 16
17 #include <assert.h>
17 #include <stdlib.h> 18 #include <stdlib.h>
18 19
19 #include "../dsp/lossless.h" 20 #include "../dsp/lossless.h"
20 #include "../utils/utils.h" 21 #include "../utils/utils.h"
21 #include "./vp8enci.h" 22 #include "./vp8enci.h"
22 23
23 #define MIN_DIM_FOR_NEAR_LOSSLESS 64 24 #define MIN_DIM_FOR_NEAR_LOSSLESS 64
24 #define MAX_LIMIT_BITS 5 25 #define MAX_LIMIT_BITS 5
25 26
26 // Computes quantized pixel value and distance from original value. 27 // Quantizes the value up or down to a multiple of 1<<bits (or to 255),
27 static void GetValAndDistance(int a, int initial, int bits, 28 // choosing the closer one, resolving ties using bankers' rounding.
28 int* const val, int* const distance) {
29 const int mask = ~((1 << bits) - 1);
30 *val = (initial & mask) | (initial >> (8 - bits));
31 *distance = 2 * abs(a - *val);
32 }
33
34 // Clamps the value to range [0, 255].
35 static int Clamp8b(int val) {
36 const int min_val = 0;
37 const int max_val = 0xff;
38 return (val < min_val) ? min_val : (val > max_val) ? max_val : val;
39 }
40
41 // Quantizes values {a, a+(1<<bits), a-(1<<bits)} and returns the nearest one.
42 static int FindClosestDiscretized(int a, int bits) { 29 static int FindClosestDiscretized(int a, int bits) {
43 int best_val = a, i; 30 const int mask = (1 << bits) - 1;
44 int min_distance = 256; 31 const int biased = a + (mask >> 1) + ((a >> bits) & 1);
45 32 assert(bits > 0);
46 for (i = -1; i <= 1; ++i) { 33 if (biased > 0xff) return 0xff;
47 int candidate, distance; 34 return biased & ~mask;
48 const int val = Clamp8b(a + i * (1 << bits));
49 GetValAndDistance(a, val, bits, &candidate, &distance);
50 if (i != 0) {
51 ++distance;
52 }
53 // Smallest distance but favor i == 0 over i == -1 and i == 1
54 // since that keeps the overall intensity more constant in the
55 // images.
56 if (distance < min_distance) {
57 min_distance = distance;
58 best_val = candidate;
59 }
60 }
61 return best_val;
62 } 35 }
63 36
64 // Applies FindClosestDiscretized to all channels of pixel. 37 // Applies FindClosestDiscretized to all channels of pixel.
65 static uint32_t ClosestDiscretizedArgb(uint32_t a, int bits) { 38 static uint32_t ClosestDiscretizedArgb(uint32_t a, int bits) {
66 return 39 return
67 (FindClosestDiscretized(a >> 24, bits) << 24) | 40 (FindClosestDiscretized(a >> 24, bits) << 24) |
68 (FindClosestDiscretized((a >> 16) & 0xff, bits) << 16) | 41 (FindClosestDiscretized((a >> 16) & 0xff, bits) << 16) |
69 (FindClosestDiscretized((a >> 8) & 0xff, bits) << 8) | 42 (FindClosestDiscretized((a >> 8) & 0xff, bits) << 8) |
70 (FindClosestDiscretized(a & 0xff, bits)); 43 (FindClosestDiscretized(a & 0xff, bits));
71 } 44 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 { 90 {
118 // Three-way swap. 91 // Three-way swap.
119 uint32_t* const temp = prev_row; 92 uint32_t* const temp = prev_row;
120 prev_row = curr_row; 93 prev_row = curr_row;
121 curr_row = next_row; 94 curr_row = next_row;
122 next_row = temp; 95 next_row = temp;
123 } 96 }
124 } 97 }
125 } 98 }
126 99
127 static int QualityToLimitBits(int quality) {
128 // quality mapping:
129 // 0..19 -> 5
130 // 0..39 -> 4
131 // 0..59 -> 3
132 // 0..79 -> 2
133 // 0..99 -> 1
134 // 100 -> 0
135 return MAX_LIMIT_BITS - quality / 20;
136 }
137
138 int VP8ApplyNearLossless(int xsize, int ysize, uint32_t* argb, int quality) { 100 int VP8ApplyNearLossless(int xsize, int ysize, uint32_t* argb, int quality) {
139 int i; 101 int i;
140 uint32_t* const copy_buffer = 102 uint32_t* const copy_buffer =
141 (uint32_t*)WebPSafeMalloc(xsize * 3, sizeof(*copy_buffer)); 103 (uint32_t*)WebPSafeMalloc(xsize * 3, sizeof(*copy_buffer));
142 const int limit_bits = QualityToLimitBits(quality); 104 const int limit_bits = VP8LNearLosslessBits(quality);
143 assert(argb != NULL); 105 assert(argb != NULL);
144 assert(limit_bits >= 0); 106 assert(limit_bits >= 0);
145 assert(limit_bits <= MAX_LIMIT_BITS); 107 assert(limit_bits <= MAX_LIMIT_BITS);
146 if (copy_buffer == NULL) { 108 if (copy_buffer == NULL) {
147 return 0; 109 return 0;
148 } 110 }
149 // For small icon images, don't attempt to apply near-lossless compression. 111 // For small icon images, don't attempt to apply near-lossless compression.
150 if (xsize < MIN_DIM_FOR_NEAR_LOSSLESS && ysize < MIN_DIM_FOR_NEAR_LOSSLESS) { 112 if (xsize < MIN_DIM_FOR_NEAR_LOSSLESS && ysize < MIN_DIM_FOR_NEAR_LOSSLESS) {
151 WebPSafeFree(copy_buffer); 113 WebPSafeFree(copy_buffer);
152 return 1; 114 return 1;
153 } 115 }
154 116
155 for (i = limit_bits; i != 0; --i) { 117 for (i = limit_bits; i != 0; --i) {
156 NearLossless(xsize, ysize, argb, i, copy_buffer); 118 NearLossless(xsize, ysize, argb, i, copy_buffer);
157 } 119 }
158 WebPSafeFree(copy_buffer); 120 WebPSafeFree(copy_buffer);
159 return 1; 121 return 1;
160 } 122 }
OLDNEW
« no previous file with comments | « third_party/libwebp/enc/histogram.c ('k') | third_party/libwebp/enc/picture.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698