OLD | NEW |
---|---|
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 Loading... | |
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 static bool SearchEOI(const char* buffer, | |
273 size_t length, | |
274 const char** eoi_ptr) { | |
kcwu
2015/08/17 06:24:13
please add comment to explain |eoi_ptr|.
It is loc
henryhsu
2015/08/17 06:52:11
Done.
| |
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) | |
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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 reader.Skip(size); | 423 reader.Skip(size); |
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 const char* eoi_ptr = nullptr; |
434 if (!SearchEOI(reader.ptr(), reader.remaining(), &eoi_ptr)) { | |
435 DLOG(ERROR) << "SearchEOI failed"; | |
436 return false; | |
437 } | |
438 result->data_size = eoi_ptr - result->data; | |
439 const int kSoiSize = 2; | |
440 result->image_size = eoi_ptr - buffer + kSoiSize; | |
375 | 441 |
376 return true; | 442 return true; |
377 } | 443 } |
378 | 444 |
379 bool ParseJpegPicture(const uint8_t* buffer, | 445 bool ParseJpegPicture(const uint8_t* buffer, |
380 size_t length, | 446 size_t length, |
381 JpegParseResult* result) { | 447 JpegParseResult* result) { |
382 DCHECK(buffer); | 448 DCHECK(buffer); |
383 DCHECK(result); | 449 DCHECK(result); |
384 BigEndianReader reader(reinterpret_cast<const char*>(buffer), length); | 450 BigEndianReader reader(reinterpret_cast<const char*>(buffer), length); |
385 memset(result, 0, sizeof(JpegParseResult)); | 451 memset(result, 0, sizeof(JpegParseResult)); |
386 | 452 |
387 uint8_t marker1, marker2; | 453 uint8_t marker1, marker2; |
388 READ_U8_OR_RETURN_FALSE(&marker1); | 454 READ_U8_OR_RETURN_FALSE(&marker1); |
389 READ_U8_OR_RETURN_FALSE(&marker2); | 455 READ_U8_OR_RETURN_FALSE(&marker2); |
390 if (marker1 != JPEG_MARKER_PREFIX || marker2 != JPEG_SOI) { | 456 if (marker1 != JPEG_MARKER_PREFIX || marker2 != JPEG_SOI) { |
391 DLOG(ERROR) << "Not a JPEG"; | 457 DLOG(ERROR) << "Not a JPEG"; |
392 return false; | 458 return false; |
393 } | 459 } |
394 | 460 |
395 return ParseSOI(reader.ptr(), reader.remaining(), result); | 461 return ParseSOI(reader.ptr(), reader.remaining(), result); |
396 } | 462 } |
397 | 463 |
398 } // namespace media | 464 } // namespace media |
OLD | NEW |