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

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 windows compile error 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
« no previous file with comments | « media/filters/jpeg_parser.h ('k') | media/filters/jpeg_parser_unittest.cc » ('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 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 marker2;
279
280 while (reader.remaining() > 0) {
281 const char* marker1_ptr = static_cast<const char*>(
282 memchr(reader.ptr(), JPEG_MARKER_PREFIX, reader.remaining()));
283 if (!marker1_ptr)
284 return false;
285 reader.Skip(marker1_ptr - reader.ptr() + 1);
286
287 do {
288 READ_U8_OR_RETURN_FALSE(&marker2);
289 } while (marker2 == JPEG_MARKER_PREFIX); // skip fill bytes
290
291 switch (marker2) {
292 // Compressed data escape.
293 case 0x00:
294 break;
295 // Restart
296 case JPEG_RST0:
297 case JPEG_RST1:
298 case JPEG_RST2:
299 case JPEG_RST3:
300 case JPEG_RST4:
301 case JPEG_RST5:
302 case JPEG_RST6:
303 case JPEG_RST7:
304 break;
305 case JPEG_EOI:
306 *eoi_ptr = reader.ptr();
307 return true;
308 default:
309 // Skip for other markers.
310 uint16_t size;
311 READ_U16_OR_RETURN_FALSE(&size);
312 if (size < sizeof(size)) {
313 DLOG(ERROR) << "Ill-formed JPEG. Segment size (" << size
314 << ") is smaller than size field (" << sizeof(size)
315 << ")";
316 return false;
317 }
318 size -= sizeof(size);
319
320 if (!reader.Skip(size)) {
321 DLOG(ERROR) << "Ill-formed JPEG. Remaining size ("
322 << reader.remaining()
323 << ") is smaller than header specified (" << size << ")";
324 return false;
325 }
326 break;
327 }
328 }
329 return false;
330 }
331
272 // |result| is already initialized to 0 in ParseJpegPicture. 332 // |result| is already initialized to 0 in ParseJpegPicture.
273 static bool ParseSOI(const char* buffer, 333 static bool ParseSOI(const char* buffer,
274 size_t length, 334 size_t length,
275 JpegParseResult* result) { 335 JpegParseResult* result) {
276 // Spec B.2.1 High-level syntax 336 // Spec B.2.1 High-level syntax
277 DCHECK(buffer); 337 DCHECK(buffer);
278 DCHECK(result); 338 DCHECK(result);
279 BigEndianReader reader(buffer, length); 339 BigEndianReader reader(buffer, length);
280 uint8_t marker1; 340 uint8_t marker1;
281 uint8_t marker2; 341 uint8_t marker2;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } 425 }
366 426
367 if (!has_marker_dqt) { 427 if (!has_marker_dqt) {
368 DLOG(ERROR) << "No DQT marker found"; 428 DLOG(ERROR) << "No DQT marker found";
369 return false; 429 return false;
370 } 430 }
371 431
372 // Scan data follows scan header immediately. 432 // Scan data follows scan header immediately.
373 result->data = reader.ptr(); 433 result->data = reader.ptr();
374 result->data_size = reader.remaining(); 434 result->data_size = reader.remaining();
435 const size_t kSoiSize = 2;
436 result->image_size = length + kSoiSize;
375 437
376 return true; 438 return true;
377 } 439 }
378 440
379 bool ParseJpegPicture(const uint8_t* buffer, 441 bool ParseJpegPicture(const uint8_t* buffer,
380 size_t length, 442 size_t length,
381 JpegParseResult* result) { 443 JpegParseResult* result) {
382 DCHECK(buffer); 444 DCHECK(buffer);
383 DCHECK(result); 445 DCHECK(result);
384 BigEndianReader reader(reinterpret_cast<const char*>(buffer), length); 446 BigEndianReader reader(reinterpret_cast<const char*>(buffer), length);
385 memset(result, 0, sizeof(JpegParseResult)); 447 memset(result, 0, sizeof(JpegParseResult));
386 448
387 uint8_t marker1, marker2; 449 uint8_t marker1, marker2;
388 READ_U8_OR_RETURN_FALSE(&marker1); 450 READ_U8_OR_RETURN_FALSE(&marker1);
389 READ_U8_OR_RETURN_FALSE(&marker2); 451 READ_U8_OR_RETURN_FALSE(&marker2);
390 if (marker1 != JPEG_MARKER_PREFIX || marker2 != JPEG_SOI) { 452 if (marker1 != JPEG_MARKER_PREFIX || marker2 != JPEG_SOI) {
391 DLOG(ERROR) << "Not a JPEG"; 453 DLOG(ERROR) << "Not a JPEG";
392 return false; 454 return false;
393 } 455 }
394 456
395 return ParseSOI(reader.ptr(), reader.remaining(), result); 457 return ParseSOI(reader.ptr(), reader.remaining(), result);
396 } 458 }
397 459
460 bool ParseJpegStream(const uint8_t* buffer,
461 size_t length,
462 JpegParseResult* result) {
463 DCHECK(buffer);
464 DCHECK(result);
465 if (!ParseJpegPicture(buffer, length, result))
466 return false;
467
468 BigEndianReader reader(
469 reinterpret_cast<const char*>(result->data), result->data_size);
470 const char* eoi_ptr = nullptr;
471 if (!SearchEOI(reader.ptr(), reader.remaining(), &eoi_ptr)) {
472 DLOG(ERROR) << "SearchEOI failed";
473 return false;
474 }
475 DCHECK(eoi_ptr);
476 result->data_size = eoi_ptr - result->data;
477 result->image_size = eoi_ptr - reinterpret_cast<const char*>(buffer);
478 return true;
479 }
480
398 } // namespace media 481 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/jpeg_parser.h ('k') | media/filters/jpeg_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698