/*
 * Copyright 2014 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: Huibao Lin

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

#include "third_party/libwebp/src/webp/decode.h"

#include "pagespeed/kernel/base/countdown_timer.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/http/image_types.pb.h"

namespace pagespeed {

namespace {

static const char kInvalidImageFormat[] = "Invalid image format";
static const char kInvalidPixelFormat[] = "Invalid pixel format";

// Magic number of the images.
const char kPngHeader[] = "\x89PNG\r\n\x1a\n";
const size_t kPngHeaderLength = arraysize(kPngHeader) - 1;
const char kGifHeader[] = "GIF8";
const size_t kGifHeaderLength = arraysize(kGifHeader) - 1;

// char to int *without sign extension*.
inline int CharToInt(char c) {
  uint8 uc = static_cast<uint8>(c);
  return static_cast<int>(uc);
}

}  // namespace

namespace image_compression {

const char* ImageFormatToMimeTypeString(ImageFormat image_type) {
  switch (image_type) {
    case IMAGE_UNKNOWN: return "image/unknown";
    case IMAGE_JPEG:    return "image/jpeg";
    case IMAGE_PNG:     return "image/png";
    case IMAGE_GIF:     return "image/gif";
    case IMAGE_WEBP:    return "image/webp";
    // No default so compiler will complain if any enum is not processed.
  }
  return kInvalidImageFormat;
}

const char* ImageFormatToString(ImageFormat image_type) {
  switch (image_type) {
    case IMAGE_UNKNOWN: return "IMAGE_UNKNOWN";
    case IMAGE_JPEG:    return "IMAGE_JPEG";
    case IMAGE_PNG:     return "IMAGE_PNG";
    case IMAGE_GIF:     return "IMAGE_GIF";
    case IMAGE_WEBP:    return "IMAGE_WEBP";
    // No default so compiler will complain if any enum is not processed.
  }
  return kInvalidImageFormat;
}

const char* GetPixelFormatString(PixelFormat pixel_format) {
  switch (pixel_format) {
    case UNSUPPORTED: return "UNSUPPORTED";
    case RGB_888:     return "RGB_888";
    case RGBA_8888:   return "RGBA_8888";
    case GRAY_8:      return "GRAY_8";
    // No default so compiler will complain if any enum is not processed.
  }
  return kInvalidPixelFormat;
}

size_t GetBytesPerPixel(PixelFormat pixel_format) {
  switch (pixel_format) {
    case UNSUPPORTED: return 0;
    case RGB_888:     return 3;
    case RGBA_8888:   return 4;
    case GRAY_8:      return 1;
    // No default so compiler will complain if any enum is not processed.
  }
  return 0;
}

net_instaweb::ImageType ComputeImageType(const StringPiece& buf) {
  // Image classification based on buffer contents gakked from leptonica,
  // but based on well-documented headers (see Wikipedia etc.).
  // Note that we can be fooled if we're passed random binary data;
  // we make the call based on as few as two bytes (JPEG).
  net_instaweb::ImageType image_type = net_instaweb::IMAGE_UNKNOWN;
  if (buf.size() >= 8) {
    // Note that gcc rightly complains about constant ranges with the
    // negative char constants unless we cast.
    switch (CharToInt(buf[0])) {
      case 0xff:
        // Either jpeg or jpeg2
        // (the latter we don't handle yet, and don't bother looking for).
        if (CharToInt(buf[1]) == 0xd8) {
          image_type = net_instaweb::IMAGE_JPEG;
        }
        break;
      case 0x89:
        // Possible png.
        if (StringPiece(buf.data(), kPngHeaderLength) ==
            StringPiece(kPngHeader, kPngHeaderLength)) {
          image_type = net_instaweb::IMAGE_PNG;
        }
        break;
      case 'G':
        // Possible gif.
        if ((StringPiece(buf.data(), kGifHeaderLength) ==
             StringPiece(kGifHeader, kGifHeaderLength)) &&
            (buf[kGifHeaderLength] == '7' || buf[kGifHeaderLength] == '9') &&
            buf[kGifHeaderLength + 1] == 'a') {
          image_type = net_instaweb::IMAGE_GIF;
        }
        break;
      case 'R':
        // Possible Webp
        // Detailed explanation on parsing webp format is available at
        // http://code.google.com/speed/webp/docs/riff_container.html
        WebPBitstreamFeatures features;
        if (WebPGetFeatures(reinterpret_cast<const uint8*>(buf.data()),
                            buf.length(), &features) ==
            VP8_STATUS_OK) {
          if (features.has_animation) {
            image_type = net_instaweb::IMAGE_WEBP_ANIMATED;
          } else if (features.format == 2 || features.has_alpha) {
            image_type = net_instaweb::IMAGE_WEBP_LOSSLESS_OR_ALPHA;
          } else if (features.format == 1) {
            image_type = net_instaweb::IMAGE_WEBP;
          }
        }
        break;
      default:
        break;
    }
  }
  return image_type;
}

bool ConversionTimeoutHandler::Continue(int percent, void* user_data) {
  ConversionTimeoutHandler* timeout_handler =
    static_cast<ConversionTimeoutHandler*>(user_data);
  if (timeout_handler != NULL &&
      !timeout_handler->countdown_timer_.HaveTimeLeft()) {
    // We include the output_->empty() check after HaveTimeLeft()
    // for testing, in case there's a callback that writes to
    // output_ invoked at a time that triggers a timeout.
    if (!timeout_handler->output_->empty()) {
      return true;
    }
    PS_LOG_WARN(timeout_handler->handler_, "Image conversion timed out.");
    timeout_handler->was_timed_out_ = true;
    return false;
  }
  return true;
}

}  // namespace image_compression

}  // namespace pagespeed
