1 /* 2 * Copyright 2012 The LibYuv Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "libyuv/mjpeg_decoder.h" 12 13 #include <string.h> // For memchr. 14 15 #ifdef __cplusplus 16 namespace libyuv { 17 extern "C" { 18 #endif 19 20 // Helper function to scan for EOI marker (0xff 0xd9). ScanEOI(const uint8 * sample,size_t sample_size)21static LIBYUV_BOOL ScanEOI(const uint8* sample, size_t sample_size) { 22 if (sample_size >= 2) { 23 const uint8* end = sample + sample_size - 1; 24 const uint8* it = sample; 25 while (it < end) { 26 // TODO(fbarchard): scan for 0xd9 instead. 27 it = static_cast<const uint8*>(memchr(it, 0xff, end - it)); 28 if (it == NULL) { 29 break; 30 } 31 if (it[1] == 0xd9) { 32 return LIBYUV_TRUE; // Success: Valid jpeg. 33 } 34 ++it; // Skip over current 0xff. 35 } 36 } 37 // ERROR: Invalid jpeg end code not found. Size sample_size 38 return LIBYUV_FALSE; 39 } 40 41 // Helper function to validate the jpeg appears intact. ValidateJpeg(const uint8 * sample,size_t sample_size)42LIBYUV_BOOL ValidateJpeg(const uint8* sample, size_t sample_size) { 43 // Maximum size that ValidateJpeg will consider valid. 44 const size_t kMaxJpegSize = 0x7fffffffull; 45 const size_t kBackSearchSize = 1024; 46 if (sample_size < 64 || sample_size > kMaxJpegSize || !sample) { 47 // ERROR: Invalid jpeg size: sample_size 48 return LIBYUV_FALSE; 49 } 50 if (sample[0] != 0xff || sample[1] != 0xd8) { // SOI marker 51 // ERROR: Invalid jpeg initial start code 52 return LIBYUV_FALSE; 53 } 54 55 // Look for the End Of Image (EOI) marker near the end of the buffer. 56 if (sample_size > kBackSearchSize) { 57 if (ScanEOI(sample + sample_size - kBackSearchSize, kBackSearchSize)) { 58 return LIBYUV_TRUE; // Success: Valid jpeg. 59 } 60 // Reduce search size for forward search. 61 sample_size = sample_size - kBackSearchSize + 1; 62 } 63 // Step over SOI marker and scan for EOI. 64 return ScanEOI(sample + 2, sample_size - 2); 65 } 66 67 #ifdef __cplusplus 68 } // extern "C" 69 } // namespace libyuv 70 #endif 71