/*
 * Copyright 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Author: Satyanarayana Manyam

#include "pagespeed/kernel/image/jpeg_utils.h"

#include <setjmp.h>  // for longjmp
// 'stdio.h' provides FILE for jpeglib (needed for certain builds)

#include <stdio.h>


#include "pagespeed/kernel/image/jpeg_reader.h"

extern "C" {
#ifdef USE_SYSTEM_LIBJPEG
#include "jpeglib.h"                                                // NOLINT
#else
#include "third_party/libjpeg_turbo/src/jpeglib.h"
#endif
}

namespace net_instaweb {
class MessageHandler;
}

namespace {
static double ComputeQualityEntriesSum(JQUANT_TBL* quantization_table,
                                       const unsigned int* std_table) {
  double quality_entries_sum = 0;

  // Quality is defined in terms of the base quantization tables used by
  // encoder. Q = quant table, q = compression quality  and S = table used by
  // encoder, Encoder does the following.
  // if q > 0.5 then Q = 2 - 2*q*S otherwise Q = (0.5/q)*S.
  //
  // Refer 'jpeg_add_quant_table (...)' in jcparam.c for more details.
  //
  // Since we don't have access to the table used by encoder. But it is
  // generally close to the standard table defined by JPEG. Hence, we apply
  // inverse function of the above to using standard table and compute the input
  // image jpeg quality.
  for (int i = 0; i < DCTSIZE2; i++) {
    if (quantization_table->quantval[i] == 1) {
      // 1 is the minimum denominator allowed for any value in the quantization
      // matrix and it implies that quality is set 100.
      quality_entries_sum += 1;
    } else {
      double scale_factor =
          static_cast<double>(quantization_table->quantval[i]) / std_table[i];
      quality_entries_sum += (scale_factor > 1.0 ?
                              (0.5/scale_factor) : ((2.0 - scale_factor)/2.0));
    }
  }

  return quality_entries_sum;
}
}  // namespace

namespace pagespeed {

namespace image_compression {

using net_instaweb::MessageHandler;

JpegUtils::JpegUtils() {
}

int JpegUtils::GetImageQualityFromImage(const void* image_data,
                                        size_t image_length,
                                        MessageHandler* handler) {
  JpegReader reader(handler);
  jpeg_decompress_struct* jpeg_decompress = reader.decompress_struct();

  // libjpeg's error handling mechanism requires that longjmp be used
  // to get control after an error.
  jmp_buf env;
  if (setjmp(env)) {
    // This code is run only when libjpeg hit an error, and called
    // longjmp(env).
    return -1;
  }

  // Need to install env so that it will be longjmp()ed to on error.
  jpeg_decompress->client_data = static_cast<void *>(&env);

  reader.PrepareForRead(image_data, image_length);

  // Read jpeg data into the decompression struct.
  jpeg_read_header(jpeg_decompress, TRUE);

  // The standard tables are taken from JPEG spec section K.1.
  static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
      16,  11,  10,  16,  24,  40,  51,  61,
      12,  12,  14,  19,  26,  58,  60,  55,
      14,  13,  16,  24,  40,  57,  69,  56,
      14,  17,  22,  29,  51,  87,  80,  62,
      18,  22,  37,  56,  68, 109, 103,  77,
      24,  35,  55,  64,  81, 104, 113,  92,
      49,  64,  78,  87, 103, 121, 120, 101,
      72,  92,  95,  98, 112, 100, 103,  99
  };
  static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
      17,  18,  24,  47,  99,  99,  99,  99,
      18,  21,  26,  66,  99,  99,  99,  99,
      24,  26,  56,  99,  99,  99,  99,  99,
      47,  66,  99,  99,  99,  99,  99,  99,
      99,  99,  99,  99,  99,  99,  99,  99,
      99,  99,  99,  99,  99,  99,  99,  99,
      99,  99,  99,  99,  99,  99,  99,  99,
      99,  99,  99,  99,  99,  99,  99,  99
  };

  double quality_entries_sum = 0;
  double quality_entries_count = 0;
  if (jpeg_decompress->quant_tbl_ptrs[0] != NULL) {
    quality_entries_sum += ComputeQualityEntriesSum(
        jpeg_decompress->quant_tbl_ptrs[0], std_luminance_quant_tbl);
    quality_entries_count += DCTSIZE2;
  }

  if (jpeg_decompress->quant_tbl_ptrs[1] != NULL) {
    quality_entries_sum += ComputeQualityEntriesSum(
        jpeg_decompress->quant_tbl_ptrs[1], std_chrominance_quant_tbl);
    quality_entries_count += DCTSIZE2;
  }

  if (quality_entries_count > 0) {
    // This computed quality is in the form of a fraction, so multiplying with
    // 100 and rounding off to nearest integer.
    double quality = quality_entries_sum * 100 / quality_entries_count;
    return static_cast<int>(quality + 0.5);
  }

  return -1;
}



}  // namespace image_compression

}  // namespace pagespeed

