OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004--2014 Google Inc. | 3 * Copyright 2004--2014 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 const int kBarcodeMaxEncodableDigits = 7; | 48 const int kBarcodeMaxEncodableDigits = 7; |
49 | 49 |
50 YuvFrameGenerator::YuvFrameGenerator(int width, int height, | 50 YuvFrameGenerator::YuvFrameGenerator(int width, int height, |
51 bool enable_barcode) { | 51 bool enable_barcode) { |
52 width_ = width; | 52 width_ = width; |
53 height_ = height; | 53 height_ = height; |
54 frame_index_ = 0; | 54 frame_index_ = 0; |
55 int size = width_ * height_; | 55 int size = width_ * height_; |
56 int qsize = size / 4; | 56 int qsize = size / 4; |
57 frame_data_size_ = size + 2 * qsize; | 57 frame_data_size_ = size + 2 * qsize; |
58 y_data_ = new uint8[size]; | 58 y_data_ = new uint8_t[size]; |
59 u_data_ = new uint8[qsize]; | 59 u_data_ = new uint8_t[qsize]; |
60 v_data_ = new uint8[qsize]; | 60 v_data_ = new uint8_t[qsize]; |
61 if (enable_barcode) { | 61 if (enable_barcode) { |
62 ASSERT(width_ >= kBarcodeBackgroundWidth); | 62 ASSERT(width_ >= kBarcodeBackgroundWidth); |
63 ASSERT(height_>= kBarcodeBackgroundHeight); | 63 ASSERT(height_>= kBarcodeBackgroundHeight); |
64 barcode_start_x_ = 0; | 64 barcode_start_x_ = 0; |
65 barcode_start_y_ = height_ - kBarcodeBackgroundHeight; | 65 barcode_start_y_ = height_ - kBarcodeBackgroundHeight; |
66 } else { | 66 } else { |
67 barcode_start_x_ = -1; | 67 barcode_start_x_ = -1; |
68 barcode_start_y_ = -1; | 68 barcode_start_y_ = -1; |
69 } | 69 } |
70 } | 70 } |
71 | 71 |
72 YuvFrameGenerator::~YuvFrameGenerator() { | 72 YuvFrameGenerator::~YuvFrameGenerator() { |
73 delete y_data_; | 73 delete y_data_; |
74 delete u_data_; | 74 delete u_data_; |
75 delete v_data_; | 75 delete v_data_; |
76 } | 76 } |
77 | 77 |
78 void YuvFrameGenerator::GenerateNextFrame(uint8* frame_buffer, | 78 void YuvFrameGenerator::GenerateNextFrame(uint8_t* frame_buffer, |
79 int32 barcode_value) { | 79 int32_t barcode_value) { |
80 int size = width_ * height_; | 80 int size = width_ * height_; |
81 int qsize = size / 4; | 81 int qsize = size / 4; |
82 memset(y_data_, 0, size); | 82 memset(y_data_, 0, size); |
83 memset(u_data_, 0, qsize); | 83 memset(u_data_, 0, qsize); |
84 memset(v_data_, 0, qsize); | 84 memset(v_data_, 0, qsize); |
85 | 85 |
86 DrawLandscape(y_data_, width_, height_); | 86 DrawLandscape(y_data_, width_, height_); |
87 DrawGradientX(u_data_, width_/2, height_/2); | 87 DrawGradientX(u_data_, width_/2, height_/2); |
88 DrawGradientY(v_data_, width_/2, height_/2); | 88 DrawGradientY(v_data_, width_/2, height_/2); |
89 DrawMovingLineX(u_data_, width_/2, height_/2, frame_index_); | 89 DrawMovingLineX(u_data_, width_/2, height_/2, frame_index_); |
90 DrawMovingLineY(v_data_, width_/2, height_/2, frame_index_); | 90 DrawMovingLineY(v_data_, width_/2, height_/2, frame_index_); |
91 DrawBouncingCube(y_data_, width_, height_, frame_index_); | 91 DrawBouncingCube(y_data_, width_, height_, frame_index_); |
92 | 92 |
93 if (barcode_value >= 0) { | 93 if (barcode_value >= 0) { |
94 ASSERT(barcode_start_x_ != -1); | 94 ASSERT(barcode_start_x_ != -1); |
95 DrawBarcode(barcode_value); | 95 DrawBarcode(barcode_value); |
96 } | 96 } |
97 | 97 |
98 memcpy(frame_buffer, y_data_, size); | 98 memcpy(frame_buffer, y_data_, size); |
99 frame_buffer += size; | 99 frame_buffer += size; |
100 memcpy(frame_buffer, u_data_, qsize); | 100 memcpy(frame_buffer, u_data_, qsize); |
101 frame_buffer += qsize; | 101 frame_buffer += qsize; |
102 memcpy(frame_buffer, v_data_, qsize); | 102 memcpy(frame_buffer, v_data_, qsize); |
103 | 103 |
104 frame_index_ = (frame_index_ + 1) & 0x0000FFFF; | 104 frame_index_ = (frame_index_ + 1) & 0x0000FFFF; |
105 } | 105 } |
106 | 106 |
107 void YuvFrameGenerator::DrawLandscape(uint8 *p, int w, int h) { | 107 void YuvFrameGenerator::DrawLandscape(uint8_t* p, int w, int h) { |
108 int x, y; | 108 int x, y; |
109 for (y = 0; y < h; y++) { | 109 for (y = 0; y < h; y++) { |
110 for (x = 0; x < w; x++) { | 110 for (x = 0; x < w; x++) { |
111 p[x + y * w] = x % (y+1); | 111 p[x + y * w] = x % (y+1); |
112 if (((x > w / 2 - (w / 32)) && (x < w / 2 + (w / 32))) || | 112 if (((x > w / 2 - (w / 32)) && (x < w / 2 + (w / 32))) || |
113 ((y > h / 2 - (h / 32)) && (y < h / 2 + (h / 32)))) { | 113 ((y > h / 2 - (h / 32)) && (y < h / 2 + (h / 32)))) { |
114 p[x + y * w] = (((x + y) / 8 % 2)) ? 255 : 0; | 114 p[x + y * w] = (((x + y) / 8 % 2)) ? 255 : 0; |
115 } | 115 } |
116 } | 116 } |
117 } | 117 } |
118 } | 118 } |
119 | 119 |
120 void YuvFrameGenerator::DrawGradientX(uint8 *p, int w, int h) { | 120 void YuvFrameGenerator::DrawGradientX(uint8_t* p, int w, int h) { |
121 int x, y; | 121 int x, y; |
122 for (y = 0; y < h; y++) { | 122 for (y = 0; y < h; y++) { |
123 for (x = 0; x < w; x++) { | 123 for (x = 0; x < w; x++) { |
124 p[x + y * w] = (x << 8) / w; | 124 p[x + y * w] = (x << 8) / w; |
125 } | 125 } |
126 } | 126 } |
127 } | 127 } |
128 | 128 |
129 void YuvFrameGenerator::DrawGradientY(uint8 *p, int w, int h) { | 129 void YuvFrameGenerator::DrawGradientY(uint8_t* p, int w, int h) { |
130 int x, y; | 130 int x, y; |
131 for (y = 0; y < h; y++) { | 131 for (y = 0; y < h; y++) { |
132 for (x = 0; x < w; x++) { | 132 for (x = 0; x < w; x++) { |
133 p[x + y * w] = (y << 8) / h; | 133 p[x + y * w] = (y << 8) / h; |
134 } | 134 } |
135 } | 135 } |
136 } | 136 } |
137 | 137 |
138 void YuvFrameGenerator::DrawMovingLineX(uint8 *p, int w, int h, int n) { | 138 void YuvFrameGenerator::DrawMovingLineX(uint8_t* p, int w, int h, int n) { |
139 int x, y; | 139 int x, y; |
140 x = n % (w * 2); | 140 x = n % (w * 2); |
141 if (x >= w) x = w + w - x - 1; | 141 if (x >= w) x = w + w - x - 1; |
142 for (y = 0; y < h; y++) { | 142 for (y = 0; y < h; y++) { |
143 p[x + y * w] = 255; | 143 p[x + y * w] = 255; |
144 } | 144 } |
145 } | 145 } |
146 | 146 |
147 void YuvFrameGenerator::DrawMovingLineY(uint8 *p, int w, int h, int n) { | 147 void YuvFrameGenerator::DrawMovingLineY(uint8_t* p, int w, int h, int n) { |
148 int x, y; | 148 int x, y; |
149 y = n % (h * 2); | 149 y = n % (h * 2); |
150 if (y >= h) y = h + h - y - 1; | 150 if (y >= h) y = h + h - y - 1; |
151 for (x = 0; x < w; x++) { | 151 for (x = 0; x < w; x++) { |
152 p[x + y * w] = 255; | 152 p[x + y * w] = 255; |
153 } | 153 } |
154 } | 154 } |
155 | 155 |
156 void YuvFrameGenerator::DrawBouncingCube(uint8 *p, int w, int h, int n) { | 156 void YuvFrameGenerator::DrawBouncingCube(uint8_t* p, int w, int h, int n) { |
157 int x, y, pw, ph, px, py; | 157 int x, y, pw, ph, px, py; |
158 pw = w / 16; | 158 pw = w / 16; |
159 ph = h / 16; | 159 ph = h / 16; |
160 px = n % (w * 2); | 160 px = n % (w * 2); |
161 py = n % (h * 2); | 161 py = n % (h * 2); |
162 if (px >= w) px = w + w - px - 1; | 162 if (px >= w) px = w + w - px - 1; |
163 if (py >= h) py = h + h - py - 1; | 163 if (py >= h) py = h + h - py - 1; |
164 for (y = py - ph; y < py + ph; y++) { | 164 for (y = py - ph; y < py + ph; y++) { |
165 if (y >=0 && y < h) { | 165 if (y >=0 && y < h) { |
166 for (x = px - pw; x < px + pw; x++) { | 166 for (x = px - pw; x < px + pw; x++) { |
167 if (x >= 0 && x < w) { | 167 if (x >= 0 && x < w) { |
168 p[x + y * w] = 255; | 168 p[x + y * w] = 255; |
169 } | 169 } |
170 } | 170 } |
171 } | 171 } |
172 } | 172 } |
173 } | 173 } |
174 | 174 |
175 void YuvFrameGenerator::GetBarcodeBounds(int* top, int* left, | 175 void YuvFrameGenerator::GetBarcodeBounds(int* top, int* left, |
176 int* width, int* height) { | 176 int* width, int* height) { |
177 ASSERT(barcode_start_x_ != -1); | 177 ASSERT(barcode_start_x_ != -1); |
178 *top = barcode_start_y_; | 178 *top = barcode_start_y_; |
179 *left = barcode_start_x_; | 179 *left = barcode_start_x_; |
180 *width = kBarcodeBackgroundWidth; | 180 *width = kBarcodeBackgroundWidth; |
181 *height = kBarcodeBackgroundHeight; | 181 *height = kBarcodeBackgroundHeight; |
182 } | 182 } |
183 | 183 |
184 static void ComputeBarcodeDigits(uint32 value, std::stringstream* result) { | 184 static void ComputeBarcodeDigits(uint32_t value, std::stringstream* result) { |
185 // Serialize |value| as 7-char string, padded with 0's to the left. | 185 // Serialize |value| as 7-char string, padded with 0's to the left. |
186 result->width(kBarcodeMaxEncodableDigits); | 186 result->width(kBarcodeMaxEncodableDigits); |
187 result->fill('0'); | 187 result->fill('0'); |
188 *result << value; | 188 *result << value; |
189 | 189 |
190 // Compute check-digit and append to result. Steps described here: | 190 // Compute check-digit and append to result. Steps described here: |
191 // http://en.wikipedia.org/wiki/European_Article_Number#Calculation_of_checksu
m_digit | 191 // http://en.wikipedia.org/wiki/European_Article_Number#Calculation_of_checksu
m_digit |
192 int sum = 0; | 192 int sum = 0; |
193 for (int pos = 1; pos <= kBarcodeMaxEncodableDigits; pos++) { | 193 for (int pos = 1; pos <= kBarcodeMaxEncodableDigits; pos++) { |
194 char next_char; | 194 char next_char; |
195 result->get(next_char); | 195 result->get(next_char); |
196 uint8 digit = next_char - '0'; | 196 uint8_t digit = next_char - '0'; |
197 sum += digit * (pos % 2 ? 3 : 1); | 197 sum += digit * (pos % 2 ? 3 : 1); |
198 } | 198 } |
199 uint8 check_digit = sum % 10; | 199 uint8_t check_digit = sum % 10; |
200 if (check_digit != 0) { | 200 if (check_digit != 0) { |
201 check_digit = 10 - check_digit; | 201 check_digit = 10 - check_digit; |
202 } | 202 } |
203 | 203 |
204 *result << static_cast<int>(check_digit); | 204 *result << static_cast<int>(check_digit); |
205 result->seekg(0); | 205 result->seekg(0); |
206 } | 206 } |
207 | 207 |
208 void YuvFrameGenerator::DrawBarcode(uint32 value) { | 208 void YuvFrameGenerator::DrawBarcode(uint32_t value) { |
209 std::stringstream value_str_stream; | 209 std::stringstream value_str_stream; |
210 ComputeBarcodeDigits(value, &value_str_stream); | 210 ComputeBarcodeDigits(value, &value_str_stream); |
211 | 211 |
212 // Draw white filled rectangle as background to barcode. | 212 // Draw white filled rectangle as background to barcode. |
213 DrawBlockRectangle(y_data_, barcode_start_x_, barcode_start_y_, | 213 DrawBlockRectangle(y_data_, barcode_start_x_, barcode_start_y_, |
214 kBarcodeBackgroundWidth, kBarcodeBackgroundHeight, | 214 kBarcodeBackgroundWidth, kBarcodeBackgroundHeight, |
215 width_, 255); | 215 width_, 255); |
216 DrawBlockRectangle(u_data_, barcode_start_x_ / 2, barcode_start_y_ / 2, | 216 DrawBlockRectangle(u_data_, barcode_start_x_ / 2, barcode_start_y_ / 2, |
217 kBarcodeBackgroundWidth / 2, kBarcodeBackgroundHeight / 2, | 217 kBarcodeBackgroundWidth / 2, kBarcodeBackgroundHeight / 2, |
218 width_ / 2, 128); | 218 width_ / 2, 128); |
219 DrawBlockRectangle(v_data_, barcode_start_x_ / 2, barcode_start_y_ / 2, | 219 DrawBlockRectangle(v_data_, barcode_start_x_ / 2, barcode_start_y_ / 2, |
220 kBarcodeBackgroundWidth / 2, kBarcodeBackgroundHeight / 2, | 220 kBarcodeBackgroundWidth / 2, kBarcodeBackgroundHeight / 2, |
221 width_ / 2, 128); | 221 width_ / 2, 128); |
222 | 222 |
223 // Scan through chars (digits) and draw black bars. | 223 // Scan through chars (digits) and draw black bars. |
224 int x = barcode_start_x_ + kBarsXOffset; | 224 int x = barcode_start_x_ + kBarsXOffset; |
225 int y = barcode_start_y_ + kBarsYOffset; | 225 int y = barcode_start_y_ + kBarsYOffset; |
226 int pos = 0; | 226 int pos = 0; |
227 x = DrawSideGuardBars(x, y, kBarcodeGuardBarHeight); | 227 x = DrawSideGuardBars(x, y, kBarcodeGuardBarHeight); |
228 while (true) { | 228 while (true) { |
229 char next_char; | 229 char next_char; |
230 value_str_stream.get(next_char); | 230 value_str_stream.get(next_char); |
231 if (!value_str_stream.good()) { | 231 if (!value_str_stream.good()) { |
232 break; | 232 break; |
233 } | 233 } |
234 if (pos++ == 4) { | 234 if (pos++ == 4) { |
235 x = DrawMiddleGuardBars(x, y, kBarcodeGuardBarHeight); | 235 x = DrawMiddleGuardBars(x, y, kBarcodeGuardBarHeight); |
236 } | 236 } |
237 uint8 digit = next_char - '0'; | 237 uint8_t digit = next_char - '0'; |
238 x = DrawEanEncodedDigit(digit, x, y, kBarcodeNormalBarHeight, pos > 4); | 238 x = DrawEanEncodedDigit(digit, x, y, kBarcodeNormalBarHeight, pos > 4); |
239 } | 239 } |
240 x = DrawSideGuardBars(x, y, kBarcodeGuardBarHeight); | 240 x = DrawSideGuardBars(x, y, kBarcodeGuardBarHeight); |
241 } | 241 } |
242 | 242 |
243 int YuvFrameGenerator::DrawMiddleGuardBars(int x, int y, int height) { | 243 int YuvFrameGenerator::DrawMiddleGuardBars(int x, int y, int height) { |
244 x += kUnitBarSize; | 244 x += kUnitBarSize; |
245 DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0); | 245 DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0); |
246 x += (kUnitBarSize * 2); | 246 x += (kUnitBarSize * 2); |
247 DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0); | 247 DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0); |
248 return x + (kUnitBarSize * 2); | 248 return x + (kUnitBarSize * 2); |
249 } | 249 } |
250 | 250 |
251 int YuvFrameGenerator::DrawSideGuardBars(int x, int y, int height) { | 251 int YuvFrameGenerator::DrawSideGuardBars(int x, int y, int height) { |
252 DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0); | 252 DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0); |
253 x += (kUnitBarSize * 2); | 253 x += (kUnitBarSize * 2); |
254 DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0); | 254 DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0); |
255 return x + kUnitBarSize; | 255 return x + kUnitBarSize; |
256 } | 256 } |
257 | 257 |
258 // For each digit: 0-9, |kEanEncodings| contains a bit-mask indicating | 258 // For each digit: 0-9, |kEanEncodings| contains a bit-mask indicating |
259 // which bars are black (1) and which are blank (0). These are for the L-code | 259 // which bars are black (1) and which are blank (0). These are for the L-code |
260 // only. R-code values are bitwise negation of these. Reference: | 260 // only. R-code values are bitwise negation of these. Reference: |
261 // http://en.wikipedia.org/wiki/European_Article_Number#Binary_encoding_of_data_
digits_into_EAN-13_barcode // NOLINT | 261 // http://en.wikipedia.org/wiki/European_Article_Number#Binary_encoding_of_data_
digits_into_EAN-13_barcode // NOLINT |
262 const uint8 kEanEncodings[] = { 13, 25, 19, 61, 35, 49, 47, 59, 55, 11 }; | 262 const uint8_t kEanEncodings[] = {13, 25, 19, 61, 35, 49, 47, 59, 55, 11}; |
263 | 263 |
264 int YuvFrameGenerator::DrawEanEncodedDigit(int digit, int x, int y, | 264 int YuvFrameGenerator::DrawEanEncodedDigit(int digit, int x, int y, |
265 int height, bool flip) { | 265 int height, bool flip) { |
266 uint8 ean_encoding = kEanEncodings[digit]; | 266 uint8_t ean_encoding = kEanEncodings[digit]; |
267 if (flip) { | 267 if (flip) { |
268 ean_encoding = ~ean_encoding; | 268 ean_encoding = ~ean_encoding; |
269 } | 269 } |
270 uint8 mask = 0x40; | 270 uint8_t mask = 0x40; |
271 for (int i = 6; i >= 0; i--, mask >>= 1) { | 271 for (int i = 6; i >= 0; i--, mask >>= 1) { |
272 if (ean_encoding & mask) { | 272 if (ean_encoding & mask) { |
273 DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0); | 273 DrawBlockRectangle(y_data_, x, y, kUnitBarSize, height, width_, 0); |
274 } | 274 } |
275 x += kUnitBarSize; | 275 x += kUnitBarSize; |
276 } | 276 } |
277 return x; | 277 return x; |
278 } | 278 } |
279 | 279 |
280 void YuvFrameGenerator::DrawBlockRectangle(uint8* p, | 280 void YuvFrameGenerator::DrawBlockRectangle(uint8_t* p, |
281 int x_start, int y_start, int width, int height, int pitch, uint8 value) { | 281 int x_start, |
| 282 int y_start, |
| 283 int width, |
| 284 int height, |
| 285 int pitch, |
| 286 uint8_t value) { |
282 for (int x = x_start; x < x_start + width; x++) { | 287 for (int x = x_start; x < x_start + width; x++) { |
283 for (int y = y_start; y < y_start + height; y++) { | 288 for (int y = y_start; y < y_start + height; y++) { |
284 p[x + y * pitch] = value; | 289 p[x + y * pitch] = value; |
285 } | 290 } |
286 } | 291 } |
287 } | 292 } |
288 | 293 |
289 } // namespace cricket | 294 } // namespace cricket |
OLD | NEW |