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

Side by Side Diff: media/filters/jpeg_parser.cc

Issue 1291933002: File video capture device supports MJPEG format (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix performance issue Created 5 years, 4 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/jpeg_parser.h" 5 #include "media/filters/jpeg_parser.h"
6 6
7 #include "base/big_endian.h" 7 #include "base/big_endian.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 9
10 using base::BigEndianReader; 10 using base::BigEndianReader;
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 return false; 262 return false;
263 } 263 }
264 if (point_transform != 0) { 264 if (point_transform != 0) {
265 DLOG(ERROR) << "Point transform should be 0 for baseline mode"; 265 DLOG(ERROR) << "Point transform should be 0 for baseline mode";
266 return false; 266 return false;
267 } 267 }
268 268
269 return true; 269 return true;
270 } 270 }
271 271
272 // |eoi_ptr| will point to the end of image (after EOI marker) after search
273 // succeeds. Returns true on EOI marker found, or false.
274 static bool SearchEOI(const char* buffer, size_t length, const char** eoi_ptr) {
275 DCHECK(buffer);
276 DCHECK(eoi_ptr);
277 BigEndianReader reader(buffer, length);
278 uint8_t marker1;
279 uint8_t marker2;
280
281 while (reader.remaining() > 0) {
282 READ_U8_OR_RETURN_FALSE(&marker1);
283 if (marker1 != JPEG_MARKER_PREFIX)
kcwu 2015/08/20 09:01:38 Does it help performance if using memcmp here?
kcwu 2015/08/20 09:18:36 I mean memchr.
henryhsu 2015/08/20 09:50:59 Yes, it help performance. Thanks.
284 continue;
285
286 do {
287 READ_U8_OR_RETURN_FALSE(&marker2);
288 } while (marker2 == JPEG_MARKER_PREFIX); // skip fill bytes
289
290 switch (marker2) {
291 // Compressed data escape.
292 case 0x00:
293 break;
294 // Restart
295 case JPEG_RST0:
296 case JPEG_RST1:
297 case JPEG_RST2:
298 case JPEG_RST3:
299 case JPEG_RST4:
300 case JPEG_RST5:
301 case JPEG_RST6:
302 case JPEG_RST7:
303 break;
304 case JPEG_EOI:
305 *eoi_ptr = reader.ptr();
306 return true;
307 default:
308 // Skip for other markers.
309 uint16_t size;
310 READ_U16_OR_RETURN_FALSE(&size);
311 if (size < sizeof(size)) {
312 DLOG(ERROR) << "Ill-formed JPEG. Segment size (" << size
313 << ") is smaller than size field (" << sizeof(size)
314 << ")";
315 return false;
316 }
317 size -= sizeof(size);
318
319 if (!reader.Skip(size)) {
320 DLOG(ERROR) << "Ill-formed JPEG. Remaining size ("
321 << reader.remaining()
322 << ") is smaller than header specified (" << size << ")";
323 return false;
324 }
325 break;
326 }
327 }
328 return false;
329 }
330
272 // |result| is already initialized to 0 in ParseJpegPicture. 331 // |result| is already initialized to 0 in ParseJpegPicture.
273 static bool ParseSOI(const char* buffer, 332 static bool ParseSOI(const char* buffer,
274 size_t length, 333 size_t length,
275 JpegParseResult* result) { 334 JpegParseResult* result) {
276 // Spec B.2.1 High-level syntax 335 // Spec B.2.1 High-level syntax
277 DCHECK(buffer); 336 DCHECK(buffer);
278 DCHECK(result); 337 DCHECK(result);
279 BigEndianReader reader(buffer, length); 338 BigEndianReader reader(buffer, length);
280 uint8_t marker1; 339 uint8_t marker1;
281 uint8_t marker2; 340 uint8_t marker2;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } 424 }
366 425
367 if (!has_marker_dqt) { 426 if (!has_marker_dqt) {
368 DLOG(ERROR) << "No DQT marker found"; 427 DLOG(ERROR) << "No DQT marker found";
369 return false; 428 return false;
370 } 429 }
371 430
372 // Scan data follows scan header immediately. 431 // Scan data follows scan header immediately.
373 result->data = reader.ptr(); 432 result->data = reader.ptr();
374 result->data_size = reader.remaining(); 433 result->data_size = reader.remaining();
434 const size_t kSoiSize = 2;
435 result->image_size = length + kSoiSize;
375 436
376 return true; 437 return true;
377 } 438 }
378 439
379 bool ParseJpegPicture(const uint8_t* buffer, 440 bool ParseJpegPicture(const uint8_t* buffer,
380 size_t length, 441 size_t length,
381 JpegParseResult* result) { 442 JpegParseResult* result) {
382 DCHECK(buffer); 443 DCHECK(buffer);
383 DCHECK(result); 444 DCHECK(result);
384 BigEndianReader reader(reinterpret_cast<const char*>(buffer), length); 445 BigEndianReader reader(reinterpret_cast<const char*>(buffer), length);
385 memset(result, 0, sizeof(JpegParseResult)); 446 memset(result, 0, sizeof(JpegParseResult));
386 447
387 uint8_t marker1, marker2; 448 uint8_t marker1, marker2;
388 READ_U8_OR_RETURN_FALSE(&marker1); 449 READ_U8_OR_RETURN_FALSE(&marker1);
389 READ_U8_OR_RETURN_FALSE(&marker2); 450 READ_U8_OR_RETURN_FALSE(&marker2);
390 if (marker1 != JPEG_MARKER_PREFIX || marker2 != JPEG_SOI) { 451 if (marker1 != JPEG_MARKER_PREFIX || marker2 != JPEG_SOI) {
391 DLOG(ERROR) << "Not a JPEG"; 452 DLOG(ERROR) << "Not a JPEG";
392 return false; 453 return false;
393 } 454 }
394 455
395 return ParseSOI(reader.ptr(), reader.remaining(), result); 456 return ParseSOI(reader.ptr(), reader.remaining(), result);
396 } 457 }
397 458
459 bool ParseJpegStream(const uint8_t* buffer,
460 size_t length,
461 JpegParseResult* result) {
462 DCHECK(buffer);
463 DCHECK(result);
464 if (!ParseJpegPicture(buffer, length, result))
465 return false;
466
467 BigEndianReader reader(
468 reinterpret_cast<const char*>(result->data), result->data_size);
469 const char* eoi_ptr = nullptr;
470 if (!SearchEOI(reader.ptr(), reader.remaining(), &eoi_ptr)) {
471 DLOG(ERROR) << "SearchEOI failed";
472 return false;
473 }
474 DCHECK(eoi_ptr);
475 result->data_size = eoi_ptr - result->data;
476 result->image_size = eoi_ptr - reinterpret_cast<const char*>(buffer);
477 return true;
478 }
479
398 } // namespace media 480 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698