| 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 |