SkJpegDecoderMgr.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Copyright 2015 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/codec/SkJpegDecoderMgr.h"
  8. #include "src/codec/SkJpegUtility.h"
  9. #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
  10. #include "include/android/SkAndroidFrameworkUtils.h"
  11. #endif
  12. /*
  13. * Print information, warning, and error messages
  14. */
  15. static void print_message(const j_common_ptr info, const char caller[]) {
  16. char buffer[JMSG_LENGTH_MAX];
  17. info->err->format_message(info, buffer);
  18. SkCodecPrintf("libjpeg error %d <%s> from %s\n", info->err->msg_code, buffer, caller);
  19. }
  20. /*
  21. * Reporting function for error and warning messages.
  22. */
  23. static void output_message(j_common_ptr info) {
  24. print_message(info, "output_message");
  25. }
  26. static void progress_monitor(j_common_ptr info) {
  27. int scan = ((j_decompress_ptr)info)->input_scan_number;
  28. // Progressive images with a very large number of scans can cause the
  29. // decoder to hang. Here we use the progress monitor to abort on
  30. // a very large number of scans. 100 is arbitrary, but much larger
  31. // than the number of scans we might expect in a normal image.
  32. if (scan >= 100) {
  33. skjpeg_err_exit(info);
  34. }
  35. }
  36. bool JpegDecoderMgr::returnFalse(const char caller[]) {
  37. print_message((j_common_ptr) &fDInfo, caller);
  38. return false;
  39. }
  40. SkCodec::Result JpegDecoderMgr::returnFailure(const char caller[], SkCodec::Result result) {
  41. print_message((j_common_ptr) &fDInfo, caller);
  42. return result;
  43. }
  44. bool JpegDecoderMgr::getEncodedColor(SkEncodedInfo::Color* outColor) {
  45. switch (fDInfo.jpeg_color_space) {
  46. case JCS_GRAYSCALE:
  47. *outColor = SkEncodedInfo::kGray_Color;
  48. return true;
  49. case JCS_YCbCr:
  50. *outColor = SkEncodedInfo::kYUV_Color;
  51. return true;
  52. case JCS_RGB:
  53. #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
  54. SkAndroidFrameworkUtils::SafetyNetLog("118372692");
  55. #endif
  56. *outColor = SkEncodedInfo::kRGB_Color;
  57. return true;
  58. case JCS_YCCK:
  59. *outColor = SkEncodedInfo::kYCCK_Color;
  60. return true;
  61. case JCS_CMYK:
  62. *outColor = SkEncodedInfo::kInvertedCMYK_Color;
  63. return true;
  64. default:
  65. return false;
  66. }
  67. }
  68. JpegDecoderMgr::JpegDecoderMgr(SkStream* stream)
  69. : fSrcMgr(stream)
  70. , fInit(false)
  71. {
  72. // Error manager must be set before any calls to libjeg in order to handle failures
  73. fDInfo.err = jpeg_std_error(&fErrorMgr);
  74. fErrorMgr.error_exit = skjpeg_err_exit;
  75. }
  76. void JpegDecoderMgr::init() {
  77. jpeg_create_decompress(&fDInfo);
  78. fInit = true;
  79. fDInfo.src = &fSrcMgr;
  80. fDInfo.err->output_message = &output_message;
  81. fDInfo.progress = &fProgressMgr;
  82. fProgressMgr.progress_monitor = &progress_monitor;
  83. }
  84. JpegDecoderMgr::~JpegDecoderMgr() {
  85. if (fInit) {
  86. jpeg_destroy_decompress(&fDInfo);
  87. }
  88. }