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_t * src_mjpg,size_t src_size_mjpg)21static LIBYUV_BOOL ScanEOI(const uint8_t* src_mjpg, size_t src_size_mjpg) { 22 if (src_size_mjpg >= 2) { 23 const uint8_t* end = src_mjpg + src_size_mjpg - 1; 24 const uint8_t* it = src_mjpg; 25 while (it < end) { 26 // TODO(fbarchard): scan for 0xd9 instead. 27 it = (const uint8_t*)(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 src_size_mjpg 38 return LIBYUV_FALSE; 39 } 40 41 // Helper function to validate the jpeg appears intact. ValidateJpeg(const uint8_t * src_mjpg,size_t src_size_mjpg)42LIBYUV_BOOL ValidateJpeg(const uint8_t* src_mjpg, size_t src_size_mjpg) { 43 // Maximum size that ValidateJpeg will consider valid. 44 const size_t kMaxJpegSize = 0x7fffffffull; 45 const size_t kBackSearchSize = 1024; 46 if (src_size_mjpg < 64 || src_size_mjpg > kMaxJpegSize || !src_mjpg) { 47 // ERROR: Invalid jpeg size: src_size_mjpg 48 return LIBYUV_FALSE; 49 } 50 // SOI marker 51 if (src_mjpg[0] != 0xff || src_mjpg[1] != 0xd8 || src_mjpg[2] != 0xff) { 52 // ERROR: Invalid jpeg initial start code 53 return LIBYUV_FALSE; 54 } 55 56 // Look for the End Of Image (EOI) marker near the end of the buffer. 57 if (src_size_mjpg > kBackSearchSize) { 58 if (ScanEOI(src_mjpg + src_size_mjpg - kBackSearchSize, kBackSearchSize)) { 59 return LIBYUV_TRUE; // Success: Valid jpeg. 60 } 61 // Reduce search size for forward search. 62 src_size_mjpg = src_size_mjpg - kBackSearchSize + 1; 63 } 64 // Step over SOI marker and scan for EOI. 65 return ScanEOI(src_mjpg + 2, src_size_mjpg - 2); 66 } 67 68 #ifdef __cplusplus 69 } // extern "C" 70 } // namespace libyuv 71 #endif 72