/*
 * 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: jmaessen@google.com (Jan Maessen)

#include "net/instaweb/rewriter/public/image_rewrite_filter.h"

#include <limits.h>
#include <sys/time.h>
#include <sys/resource.h>

#include <algorithm>
#include <cstdarg>
#include <utility>
#include <vector>

#include "base/logging.h"
#include "net/instaweb/http/public/log_record.h"
#include "net/instaweb/http/public/logging_proto.h"
#include "net/instaweb/http/public/logging_proto_impl.h"
#include "net/instaweb/http/public/request_context.h"
#include "net/instaweb/rewriter/cached_result.pb.h"
#include "net/instaweb/rewriter/public/central_controller_interface_adapter.h"
#include "net/instaweb/rewriter/public/critical_images_beacon_filter.h"
#include "net/instaweb/rewriter/public/critical_images_finder.h"
#include "net/instaweb/rewriter/public/css_url_encoder.h"
#include "net/instaweb/rewriter/public/css_util.h"
#include "net/instaweb/rewriter/public/image.h"
#include "net/instaweb/rewriter/public/local_storage_cache_filter.h"
#include "net/instaweb/rewriter/public/output_resource.h"
#include "net/instaweb/rewriter/public/output_resource_kind.h"
#include "net/instaweb/rewriter/public/request_properties.h"
#include "net/instaweb/rewriter/public/resource.h"
#include "net/instaweb/rewriter/public/resource_namer.h"
#include "net/instaweb/rewriter/public/resource_slot.h"
#include "net/instaweb/rewriter/public/resource_tag_scanner.h"
#include "net/instaweb/rewriter/public/responsive_image_filter.h"
#include "net/instaweb/rewriter/public/rewrite_context.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_driver_factory.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "net/instaweb/rewriter/public/single_rewrite_context.h"
#include "net/instaweb/util/public/property_cache.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/escaping.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/statistics.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/html/html_element.h"
#include "pagespeed/kernel/html/html_name.h"
#include "pagespeed/kernel/html/html_node.h"
#include "pagespeed/kernel/http/content_type.h"
#include "pagespeed/kernel/http/data_url.h"
#include "pagespeed/kernel/http/google_url.h"
#include "pagespeed/kernel/http/response_headers.h"
#include "pagespeed/kernel/http/semantic_type.h"
#include "pagespeed/kernel/image/image_util.h"
#include "pagespeed/kernel/thread/queued_worker_pool.h"
#include "pagespeed/kernel/util/simple_random.h"
#include "pagespeed/opt/logging/enums.pb.h"

namespace net_instaweb {

namespace {

void DetermineQualities(const RewriteOptions& options,
                        const ResourceContext& resource_context,
                        const RequestProperties& request_properties,
                        Image::CompressionOptions* image_options) {
  if (resource_context.may_use_save_data_quality()) {
    // Use Save-Data qualities.
    image_options->webp_quality = options.ImageWebpQualityForSaveData();
    image_options->webp_animated_quality =
      options.ImageWebpQualityForSaveData();
    image_options->jpeg_quality = options.ImageJpegQualityForSaveData();
    image_options->jpeg_num_progressive_scans =
      options.image_jpeg_num_progressive_scans();
  } else if (resource_context.may_use_small_screen_quality()) {
    // Use small screen qualities.
    image_options->webp_quality = options.ImageWebpQualityForSmallScreen();
    image_options->webp_animated_quality = options.ImageWebpAnimatedQuality();
    image_options->jpeg_quality = options.ImageJpegQualityForSmallScreen();
    image_options->jpeg_num_progressive_scans =
        options.ImageJpegNumProgressiveScansForSmallScreen();
  } else {
    // Use regular (desktop) qualities.
    image_options->webp_quality = options.ImageWebpQuality();
    image_options->webp_animated_quality = options.ImageWebpAnimatedQuality();
    image_options->jpeg_quality = options.ImageJpegQuality();
    image_options->jpeg_num_progressive_scans =
        options.image_jpeg_num_progressive_scans();
  }
}

int64 GetPageWidth(const int64 page_height,
                   const int64 image_width,
                   const int64 image_height) {
  if (image_height > 0) {
    return (page_height * image_width + image_height / 2) / image_height;
  } else {
    // The client should ensure that "image_height > 0". If this condition is
    // not met, we protect against division by 0 by returning 0 so that resize
    // attempts will fail.
    return 0;
  }
}

int64 GetPageHeight(const int64 page_width,
                    const int64 image_height,
                    const int64 image_width) {
  if (image_height > 0) {
    return (page_width * image_height + image_width / 2) / image_width;
  } else {
    // The client should ensure that "image_width > 0". If this condition is
    // not met, we protect against division by 0 by returning 0 so that resize
    // attempts will fail.
    return 0;
  }
}

void SetDesiredDimensionsIfRequired(ImageDim* desired_dim,
                                    const ImageDim& image_dim) {
  if (!ImageUrlEncoder::HasValidDimension(*desired_dim)) {
    return;
  }
  int32 page_width = desired_dim->width();  // Rendered width.
  int32 page_height = desired_dim->height();  // Rendered height.
  const int64 image_width = image_dim.width();
  const int64 image_height = image_dim.height();
  if (!desired_dim->has_width()) {
    // Fill in a missing page height:
    //   page_height * (image_width / image_height),
    // rounding the result.
    // To avoid fractions we instead group as
    //   (page_height * image_width) / image_height and do the
    // math in int64 to avoid overflow in the numerator.  The additional
    // image_height / 2 causes us to round rather than truncate.
    desired_dim->set_height(page_height);
    desired_dim->set_width(static_cast<int32>(GetPageWidth(
        page_height, image_width, image_height)));
  } else if (!desired_dim->has_height()) {
    desired_dim->set_width(page_width);
    desired_dim->set_height(static_cast<int32>(GetPageHeight(
        page_width, image_height, image_width)));
  }
}

// Returns true if the low-res image can be inline-previewed.
bool ShouldInlinePreview(const int64 low_res_size, const int64 full_res_size,
                         const RewriteOptions* options) {
  bool low_res_is_small = options->max_low_res_image_size_bytes() < 0 ||
      low_res_size <= options->max_low_res_image_size_bytes();
  bool low_res_smaller_than_full_res =
      low_res_size * 100 < full_res_size *
      options->max_low_res_to_full_res_image_size_percentage();
  return (low_res_is_small && low_res_smaller_than_full_res);
}

const char* const kRelatedOptions[] = {
  RewriteOptions::kImageJpegNumProgressiveScans,
  RewriteOptions::kImageJpegNumProgressiveScansForSmallScreens,
  RewriteOptions::kImageJpegRecompressionQuality,
  RewriteOptions::kImageJpegRecompressionQualityForSmallScreens,
  RewriteOptions::kImageJpegQualityForSaveData,
  RewriteOptions::kImageLimitOptimizedPercent,
  RewriteOptions::kImageLimitResizeAreaPercent,
  RewriteOptions::kImageMaxRewritesAtOnce,
  RewriteOptions::kImagePreserveURLs,
  RewriteOptions::kImageRecompressionQuality,
  RewriteOptions::kImageResolutionLimitBytes,
  RewriteOptions::kImageWebpRecompressionQuality,
  RewriteOptions::kImageWebpRecompressionQualityForSmallScreens,
  RewriteOptions::kImageWebpAnimatedRecompressionQuality,
  RewriteOptions::kImageWebpQualityForSaveData,
  RewriteOptions::kProgressiveJpegMinBytes
};

}  // namespace

// Expose kRelatedFilters as a class variable for the benefit of
// static-init-time merging in css_filter.cc.
const RewriteOptions::Filter ImageRewriteFilter::kRelatedFilters[] = {
  RewriteOptions::kConvertGifToPng,
  RewriteOptions::kConvertJpegToProgressive,
  RewriteOptions::kConvertJpegToWebp,
  RewriteOptions::kConvertPngToJpeg,
  RewriteOptions::kConvertToWebpAnimated,
  RewriteOptions::kConvertToWebpLossless,
  RewriteOptions::kJpegSubsampling,
  RewriteOptions::kRecompressJpeg,
  RewriteOptions::kRecompressPng,
  RewriteOptions::kRecompressWebp,
  RewriteOptions::kResizeImages,
  RewriteOptions::kResizeMobileImages,
  RewriteOptions::kStripImageColorProfile,
  RewriteOptions::kStripImageMetaData
};
const int ImageRewriteFilter::kRelatedFiltersSize = arraysize(kRelatedFilters);

StringPieceVector* ImageRewriteFilter::related_options_ = NULL;

// names for Statistics variables.
const char ImageRewriteFilter::kImageRewrites[] = "image_rewrites";
const char ImageRewriteFilter::kImageNoRewritesHighResolution[] =
    "image_norewrites_high_resolution";
const char kImageRewritesDroppedIntentionally[] =
    "image_rewrites_dropped_intentionally";
const char ImageRewriteFilter::kImageRewritesDroppedDecodeFailure[] =
    "image_rewrites_dropped_decode_failure";
const char ImageRewriteFilter::kImageRewritesDroppedServerWriteFail[] =
    "image_rewrites_dropped_server_write_fail";
const char ImageRewriteFilter::kImageRewritesDroppedMIMETypeUnknown[] =
    "image_rewrites_dropped_mime_type_unknown";
const char ImageRewriteFilter::kImageRewritesDroppedNoSavingResize[] =
    "image_rewrites_dropped_nosaving_resize";
const char ImageRewriteFilter::kImageRewritesDroppedNoSavingNoResize[] =
    "image_rewrites_dropped_nosaving_noresize";
const char ImageRewriteFilter::kImageRewritesDroppedDueToLoad[] =
    "image_rewrites_dropped_due_to_load";
const char ImageRewriteFilter::kImageRewritesSquashingForMobileScreen[] =
    "image_rewrites_squashing_for_mobile_screen";
const char kImageRewriteTotalBytesSaved[] = "image_rewrite_total_bytes_saved";
const char kImageRewriteTotalOriginalBytes[] =
    "image_rewrite_total_original_bytes";
const char kImageRewriteUses[] = "image_rewrite_uses";
const char kImageInline[] = "image_inline";
const char ImageRewriteFilter::kImageOngoingRewrites[] =
    "image_ongoing_rewrites";
const char ImageRewriteFilter::kImageResizedUsingRenderedDimensions[] =
    "image_resized_using_rendered_dimensions";
const char ImageRewriteFilter::kImageWebpRewrites[] = "image_webp_rewrites";
const char ImageRewriteFilter::kInlinableImageUrlsPropertyName[] =
    "ImageRewriter-inlinable-urls";
const char ImageRewriteFilter::kImageRewriteLatencyOkMs[] =
    "image_rewrite_latency_ok_ms";
const char ImageRewriteFilter::kImageRewriteLatencyFailedMs[] =
    "image_rewrite_latency_failed_ms";
const char ImageRewriteFilter::kImageRewriteLatencyTotalMs[] =
    "image_rewrite_latency_total_ms";

const char ImageRewriteFilter::kImageWebpFromGifTimeouts[] =
    "image_webp_conversion_gif_timeouts";
const char ImageRewriteFilter::kImageWebpFromPngTimeouts[] =
    "image_webp_conversion_png_timeouts";
const char ImageRewriteFilter::kImageWebpFromJpegTimeouts[] =
    "image_webp_conversion_jpeg_timeouts";
const char ImageRewriteFilter::kImageWebpFromGifAnimatedTimeouts[] =
    "image_webp_conversion_gif_animated_timeouts";

const char ImageRewriteFilter::kImageWebpFromGifSuccessMs[] =
    "image_webp_conversion_gif_success_ms";
const char ImageRewriteFilter::kImageWebpFromPngSuccessMs[] =
    "image_webp_conversion_png_success_ms";
const char ImageRewriteFilter::kImageWebpFromJpegSuccessMs[] =
    "image_webp_conversion_jpeg_success_ms";
const char ImageRewriteFilter::kImageWebpFromGifAnimatedSuccessMs[] =
    "image_webp_conversion_gif_animated_success_ms";

const char ImageRewriteFilter::kImageWebpFromGifFailureMs[] =
    "image_webp_conversion_gif_failure_ms";
const char ImageRewriteFilter::kImageWebpFromPngFailureMs[] =
    "image_webp_conversion_png_failure_ms";
const char ImageRewriteFilter::kImageWebpFromJpegFailureMs[] =
    "image_webp_conversion_jpeg_failure_ms";
const char ImageRewriteFilter::kImageWebpFromGifAnimatedFailureMs[] =
    "image_webp_conversion_gif_animated_failure_ms";

const char ImageRewriteFilter::kImageWebpWithAlphaTimeouts[] =
    "image_webp_alpha_timeouts";
const char ImageRewriteFilter::kImageWebpWithAlphaSuccessMs[] =
    "image_webp_alpha_success_ms";
const char ImageRewriteFilter::kImageWebpWithAlphaFailureMs[] =
    "image_webp_alpha_failure_ms";

const char ImageRewriteFilter::kImageWebpOpaqueTimeouts[] =
    "image_webp_opaque_timeouts";
const char ImageRewriteFilter::kImageWebpOpaqueSuccessMs[] =
    "image_webp_opaque_success_ms";
const char ImageRewriteFilter::kImageWebpOpaqueFailureMs[] =
    "image_webp_opaque_failure_ms";

const int kNotCriticalIndex = INT_MAX;

// This is the resized placeholder image width for mobile.
const int kDelayImageWidthForMobile = 320;

namespace {

void LogImageBackgroundRewriteActivity(
    RewriteDriver* driver,
    RewriterApplication::Status status,
    const GoogleString& url,
    const char* id,
    int original_size,
    int optimized_size,
    bool is_recompressed,
    ImageType original_image_type,
    ImageType optimized_image_type,
    bool is_resized,
    int original_width,
    int original_height,
    bool is_resized_using_rendered_dimensions,
    int resized_width,
    int resized_height) {
  const RewriteOptions* options = driver->options();
  if (!options->log_background_rewrites()) {
    return;
  }

  AbstractLogRecord* log_record =
      driver->request_context()->GetBackgroundRewriteLog(
          driver->server_context()->thread_system(),
          options->allow_logging_urls_in_log_record(),
          options->log_url_indices(),
          options->max_rewrite_info_log_size());

  // Write log for background rewrites.
  log_record->LogImageBackgroundRewriteActivity(status, url, id, original_size,
      optimized_size, is_recompressed, original_image_type,
      optimized_image_type, is_resized, original_width, original_height,
      is_resized_using_rendered_dimensions, resized_width, resized_height);
}

const char* MessageForInlineResult(InlineResult inline_result) {
  const char* message = "";
  switch (inline_result) {
    case INLINE_SUCCESS:
      // No message will be displayed.
      break;
    case INLINE_UNSUPPORTED_DEVICE:
      message = "The image was not inlined because device does not support "
        "inlinling.";
      break;
    case INLINE_NOT_CRITICAL:
      message = "The image was not inlined because you have chosen to only "
        "inline the critical images but this image is not critical.";
      break;
    case INLINE_NO_DATA:
    case INLINE_TOO_LARGE:
      message = "The image was not inlined because it has too many bytes.";
      break;
    case INLINE_CACHE_SMALL_IMAGES_UNREWRITTEN:
      message = "The image was not inlined because CacheSmallImagesUnrewritten "
        "has been set.";
      break;
    case INLINE_RESPONSIVE:
      // Don't add any debug message for virtual responsive images. This virtual
      // image will be deleted before the user sees it, so message won't be
      // useful.
      break;
    case INLINE_SHORTCUT:
      message = "The image was not inlined because it is a shortcut icon.";
      break;
    case INLINE_INTERNAL_ERROR:
      message = "The image was not inlined because the internal data was "
        "corrupted.";
      break;
  }
  return message;
}

}  // namespace

class ImageRewriteFilter::Context : public SingleRewriteContext {
 public:
  Context(int64 css_image_inline_max_bytes,
          ImageRewriteFilter* filter, RewriteDriver* driver,
          RewriteContext* parent, ResourceContext* resource_context,
          bool is_css, int html_index, bool in_noscript_element,
          bool is_resized_using_rendered_dimensions)
      : SingleRewriteContext(driver, parent, resource_context),
        css_image_inline_max_bytes_(css_image_inline_max_bytes),
        filter_(filter),
        is_css_(is_css),
        html_index_(html_index),
        in_noscript_element_(in_noscript_element),
        is_resized_using_rendered_dimensions_(
            is_resized_using_rendered_dimensions) {}
  virtual ~Context() {}

  virtual void Render();
  virtual void RewriteSingle(const ResourcePtr& input,
                             const OutputResourcePtr& output);
  virtual const char* id() const { return filter_->id(); }
  virtual OutputResourceKind kind() const { return kRewrittenResource; }
  virtual const UrlSegmentEncoder* encoder() const;

  // Implements UserAgentCacheKey method of RewriteContext.
  virtual GoogleString UserAgentCacheKey(
      const ResourceContext* resource_context) const;

  // Implements EncodeUserAgentIntoResourceContext of RewriteContext.
  virtual void EncodeUserAgentIntoResourceContext(
      ResourceContext* context);

 private:
  class InvokeRewriteFunction;

  friend class ImageRewriteFilter;

  int64 css_image_inline_max_bytes_;
  ImageRewriteFilter* filter_;
  bool is_css_;
  const int html_index_;
  bool in_noscript_element_;
  bool is_resized_using_rendered_dimensions_;
  DISALLOW_COPY_AND_ASSIGN(Context);
};

class ImageRewriteFilter::Context::InvokeRewriteFunction
    : public ExpensiveOperationCallback {
 public:
  InvokeRewriteFunction(ImageRewriteFilter::Context* context,
                        ImageRewriteFilter* filter,
                        const ResourcePtr& input_resource,
                        const OutputResourcePtr& output_resource)
      : ExpensiveOperationCallback(
            context->Driver()->low_priority_rewrite_worker()),
        context_(context),
        filter_(filter),
        input_resource_(input_resource),
        output_resource_(output_resource) {}
  virtual ~InvokeRewriteFunction() { }

 protected:
  virtual void RunImpl(scoped_ptr<ExpensiveOperationContext>* context) {
    RewriteResult result = filter_->RewriteLoadedResourceImpl(
        context_, input_resource_, output_resource_);
    (*context)->Done();
    context_->RewriteDone(result, 0);
  }

  virtual void CancelImpl() {
    filter_->ReportDroppedRewrite();
    filter_->InfoAndTrace(context_, "%s: Too busy to rewrite image.",
                          input_resource_->url().c_str());
    context_->RewriteDone(kTooBusy, 0);
  }

 private:
  ImageRewriteFilter::Context* context_;
  ImageRewriteFilter* filter_;
  const ResourcePtr input_resource_;
  const OutputResourcePtr output_resource_;

  DISALLOW_COPY_AND_ASSIGN(InvokeRewriteFunction);
};

// TODO(huibao): Move the logic for determining output format to a centralized
// method which should consider all relevant factors.
void SetWebpCompressionOptions(
    const ResourceContext& resource_context,
    const RewriteOptions& options,
    const StringPiece& url,
    Image::ConversionVariables* webp_conversion_variables,
    Image::CompressionOptions* image_options) {
  switch (resource_context.libwebp_level()) {
      case ResourceContext::LIBWEBP_NONE:
        image_options->preferred_webp = pagespeed::image_compression::WEBP_NONE;
        image_options->allow_webp_alpha = false;
        VLOG(1) << "User agent is not webp capable";
        break;

      case ResourceContext::LIBWEBP_LOSSY_ONLY:
        image_options->preferred_webp =
            pagespeed::image_compression::WEBP_LOSSY;
        image_options->allow_webp_alpha = false;
        VLOG(1) << "User agent is webp lossy capable ";
        break;

      case ResourceContext::LIBWEBP_ANIMATED:
        if (options.Enabled(RewriteOptions::kConvertToWebpAnimated)) {
          image_options->preferred_webp =
              pagespeed::image_compression::WEBP_ANIMATED;
          image_options->allow_webp_animated = true;
          image_options->allow_webp_alpha = true;
          break;
        }
        VLOG(1) << "User agent is webp animated capable ";
        FALLTHROUGH_INTENDED;

      case ResourceContext::LIBWEBP_LOSSY_LOSSLESS_ALPHA:
        image_options->allow_webp_alpha = true;
        if (options.Enabled(RewriteOptions::kConvertToWebpLossless)) {
          image_options->preferred_webp =
              pagespeed::image_compression::WEBP_LOSSLESS;
          VLOG(1) << "User agent is webp lossless+alpha capable "
                  << "and lossless images preferred";
        } else {
          image_options->preferred_webp =
              pagespeed::image_compression::WEBP_LOSSY;
          VLOG(1) << "User agent is webp lossless+alpha capable "
                  << "and lossy images preferred";
        }
        break;
      default:
        LOG(DFATAL) << "Unhandled libwebp_level";
  }
  image_options->webp_conversion_variables = webp_conversion_variables;
}

void ImageRewriteFilter::Context::RewriteSingle(
    const ResourcePtr& input_resource,
    const OutputResourcePtr& output_resource) {
  // If requested, drop random image rewrites. Eventually, frequently requested
  // images will get optimized but the long tail won't be optimized much. We're
  // not particularly concerned about the quality of the PRNG here as it's just
  // deciding if we should optimize an image or not.
  int drop_percentage = Options()->rewrite_random_drop_percentage();
  if (drop_percentage > 0 && !IsNestedIn(RewriteOptions::kCssFilterId)) {
    // Note that we don't randomly drop if this is a nested context of the CSS
    // filter as we don't want to partially rewrite a CSS file.
    SimpleRandom* simple_random = FindServerContext()->simple_random();
    if (drop_percentage > static_cast<int>(simple_random->Next() % 100)) {
      RewriteDone(kTooBusy, 0);
      return;
    }
  }
  bool is_ipro = IsNestedIn(RewriteOptions::kInPlaceRewriteId);
  AttachDependentRequestTrace(is_ipro ? "IproProcessImage" : "ProcessImage");
  AddLinkRelCanonical(input_resource, output_resource);
  FindServerContext()->factory()->ScheduleExpensiveOperation(
      new InvokeRewriteFunction(this, filter_, input_resource,
                                output_resource));
}

void ImageRewriteFilter::Context::Render() {
  if (num_output_partitions() != 1) {
    // Partition failed since one of the inputs was unavailable; nothing to do.
    return;
  }

  CHECK_EQ(1, num_slots());

  CachedResult* result = output_partition(0);
  bool rewrote_url = false;
  ResourceSlot* resource_slot = slot(0).get();
  if (is_css_ || !has_parent()) {
    InlineResult inline_result;
    if (is_css_) {
      rewrote_url = filter_->FinishRewriteCssImageUrl(
          css_image_inline_max_bytes_, result, resource_slot, &inline_result);
    } else {  // html
      // We use manual rendering for HTML, as we have to consider whether to
      // inline, and may also pass in width and height attributes.
      HtmlResourceSlot* html_slot = static_cast<HtmlResourceSlot*>(
          resource_slot);
      rewrote_url = filter_->FinishRewriteImageUrl(
          result, resource_context(), html_slot->element(),
          html_slot->attribute(), html_index_, html_slot, &inline_result);

      // Register image metrics for images inside HTML here. We don't deal with
      // images inside CSS here since we might not even run --- our work may get
      // cached at CSS filter level.
      if (Driver()->options()->Enabled(
              RewriteOptions::kExperimentCollectMobImageInfo)) {
        AssociatedImageInfo aii;
        if (ExtractAssociatedImageInfo(result, this, &aii)) {
          filter_->RegisterImageInfo(aii);
        }
      }
    }

    if (Driver()->options()->Enabled(RewriteOptions::kInlineImages)) {
      // Show the debug message for inlining only when this option has been
      // enabled.
      // Note: Although debug message is saved to the cached_result, it is
      // *not* cached because the cached_result has already been stored in
      // the cache previously. This is good because the exact debug message
      // here depends upon factors that may not be in the cache key (such
      // as whether this is a responsive image). So we should not be storing
      // the result in the cache.
      filter_->SaveDebugMessageToCache(
          MessageForInlineResult(inline_result), this, result);
    }
    // Use standard rendering in case the rewrite is nested and not inside CSS.
  }
  if (rewrote_url) {
    // We wrote out the URL ourselves; don't let the default handling mess it up
    // (in particular replacing data: with out-of-line version)
    resource_slot->set_disable_rendering(true);
  }
}

const UrlSegmentEncoder* ImageRewriteFilter::Context::encoder() const {
  return filter_->encoder();
}

GoogleString ImageRewriteFilter::Context::UserAgentCacheKey(
    const ResourceContext* resource_context) const {
  if (resource_context != NULL) {
    // cache-key is sensitive to whether the UA supports webp or not.
    return ImageUrlEncoder::CacheKeyFromResourceContext(*resource_context);
  }
  return "";
}

void ImageRewriteFilter::Context::EncodeUserAgentIntoResourceContext(
    ResourceContext* context) {
  filter_->EncodeUserAgentIntoResourceContext(context);
}

ImageRewriteFilter::ImageRewriteFilter(RewriteDriver* driver)
    : RewriteFilter(driver),
      image_counter_(0),
      saw_end_document_(false) {
  Statistics* stats = server_context()->statistics();
  image_rewrites_ = stats->GetVariable(kImageRewrites);
  image_resized_using_rendered_dimensions_ =
      stats->GetVariable(kImageResizedUsingRenderedDimensions);
  image_norewrites_high_resolution_ = stats->GetVariable(
      kImageNoRewritesHighResolution);
  image_rewrites_dropped_intentionally_ =
      stats->GetVariable(kImageRewritesDroppedIntentionally);
  image_rewrites_dropped_decode_failure_ =
      stats->GetVariable(kImageRewritesDroppedDecodeFailure);
  image_rewrites_dropped_server_write_fail_ =
      stats->GetVariable(kImageRewritesDroppedServerWriteFail);
  image_rewrites_dropped_mime_type_unknown_ =
      stats->GetVariable(kImageRewritesDroppedMIMETypeUnknown);
  image_rewrites_dropped_nosaving_resize_ =
      stats->GetVariable(kImageRewritesDroppedNoSavingResize);
  image_rewrites_dropped_nosaving_noresize_ =
      stats->GetVariable(kImageRewritesDroppedNoSavingNoResize);
  image_rewrites_dropped_due_to_load_ =
      stats->GetTimedVariable(kImageRewritesDroppedDueToLoad);
  image_rewrites_squashing_for_mobile_screen_ =
      stats->GetTimedVariable(kImageRewritesSquashingForMobileScreen);
  image_rewrite_total_bytes_saved_ =
      stats->GetVariable(kImageRewriteTotalBytesSaved);
  image_rewrite_total_original_bytes_ =
      stats->GetVariable(kImageRewriteTotalOriginalBytes);
  image_rewrite_uses_ = stats->GetVariable(kImageRewriteUses);
  image_inline_count_ = stats->GetVariable(kImageInline);
  image_webp_rewrites_ = stats->GetVariable(kImageWebpRewrites);
  image_rewrite_latency_total_ms_ =
      stats->GetVariable(kImageRewriteLatencyTotalMs);

  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_GIF)->timeout_count =
      stats->GetVariable(kImageWebpFromGifTimeouts);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_PNG)->timeout_count =
      stats->GetVariable(kImageWebpFromPngTimeouts);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_JPEG)->timeout_count =
      stats->GetVariable(kImageWebpFromJpegTimeouts);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_GIF_ANIMATED)->timeout_count =
      stats->GetVariable(kImageWebpFromGifAnimatedTimeouts);

  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_GIF)->success_ms =
      stats->GetHistogram(kImageWebpFromGifSuccessMs);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_PNG)->success_ms =
      stats->GetHistogram(kImageWebpFromPngSuccessMs);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_JPEG)->success_ms =
      stats->GetHistogram(kImageWebpFromJpegSuccessMs);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_GIF_ANIMATED)->success_ms =
      stats->GetHistogram(kImageWebpFromGifAnimatedSuccessMs);

  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_GIF)->failure_ms =
      stats->GetHistogram(kImageWebpFromGifFailureMs);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_PNG)->failure_ms =
      stats->GetHistogram(kImageWebpFromPngFailureMs);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_JPEG)->failure_ms =
      stats->GetHistogram(kImageWebpFromJpegFailureMs);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::FROM_GIF_ANIMATED)->failure_ms =
      stats->GetHistogram(kImageWebpFromGifAnimatedFailureMs);

  webp_conversion_variables_.Get(
      Image::ConversionVariables::NONOPAQUE)->timeout_count =
      stats->GetVariable(kImageWebpWithAlphaTimeouts);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::NONOPAQUE)->success_ms =
      stats->GetHistogram(kImageWebpWithAlphaSuccessMs);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::NONOPAQUE)->failure_ms =
      stats->GetHistogram(kImageWebpWithAlphaFailureMs);

  webp_conversion_variables_.Get(
      Image::ConversionVariables::OPAQUE)->timeout_count =
      stats->GetVariable(kImageWebpOpaqueTimeouts);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::OPAQUE)->success_ms =
      stats->GetHistogram(kImageWebpOpaqueSuccessMs);
  webp_conversion_variables_.Get(
      Image::ConversionVariables::OPAQUE)->failure_ms =
      stats->GetHistogram(kImageWebpOpaqueFailureMs);

  image_rewrite_latency_ok_ms_ = stats->GetHistogram(kImageRewriteLatencyOkMs);
  image_rewrite_latency_failed_ms_ =
      stats->GetHistogram(kImageRewriteLatencyFailedMs);

  image_ongoing_rewrites_ = stats->GetUpDownCounter(kImageOngoingRewrites);
}

ImageRewriteFilter::~ImageRewriteFilter() {}

void ImageRewriteFilter::InitStats(Statistics* statistics) {
#ifndef NDEBUG
  for (int i = 1; i < kRelatedFiltersSize; ++i) {
    CHECK_LT(kRelatedFilters[i - 1], kRelatedFilters[i])
        << "kRelatedFilters not in enum-value order";
  }
#endif

  statistics->AddVariable(kImageRewrites);
  statistics->AddVariable(kImageResizedUsingRenderedDimensions);
  statistics->AddVariable(kImageNoRewritesHighResolution);
  statistics->AddVariable(kImageRewritesDroppedIntentionally);
  statistics->AddVariable(kImageRewritesDroppedDecodeFailure);
  statistics->AddVariable(kImageRewritesDroppedMIMETypeUnknown);
  statistics->AddVariable(kImageRewritesDroppedServerWriteFail);
  statistics->AddVariable(kImageRewritesDroppedNoSavingResize);
  statistics->AddVariable(kImageRewritesDroppedNoSavingNoResize);
  statistics->AddTimedVariable(kImageRewritesDroppedDueToLoad,
                               ServerContext::kStatisticsGroup);
  statistics->AddTimedVariable(kImageRewritesSquashingForMobileScreen,
                               ServerContext::kStatisticsGroup);
  statistics->AddVariable(kImageRewriteTotalBytesSaved);
  statistics->AddVariable(kImageRewriteTotalOriginalBytes);
  statistics->AddVariable(kImageRewriteUses);
  statistics->AddVariable(kImageInline);
  statistics->AddVariable(kImageWebpRewrites);
  statistics->AddVariable(kImageRewriteLatencyTotalMs);
  statistics->AddUpDownCounter(kImageOngoingRewrites);
  statistics->AddHistogram(kImageRewriteLatencyOkMs);
  statistics->AddHistogram(kImageRewriteLatencyFailedMs);

  statistics->AddVariable(kImageWebpFromGifTimeouts);
  statistics->AddVariable(kImageWebpFromPngTimeouts);
  statistics->AddVariable(kImageWebpFromJpegTimeouts);
  statistics->AddVariable(kImageWebpFromGifAnimatedTimeouts);

  statistics->AddHistogram(kImageWebpFromGifSuccessMs);
  statistics->AddHistogram(kImageWebpFromPngSuccessMs);
  statistics->AddHistogram(kImageWebpFromJpegSuccessMs);
  statistics->AddHistogram(kImageWebpFromGifAnimatedSuccessMs);

  statistics->AddHistogram(kImageWebpFromGifFailureMs);
  statistics->AddHistogram(kImageWebpFromPngFailureMs);
  statistics->AddHistogram(kImageWebpFromJpegFailureMs);
  statistics->AddHistogram(kImageWebpFromGifAnimatedFailureMs);

  statistics->AddVariable(kImageWebpWithAlphaTimeouts);
  statistics->AddHistogram(kImageWebpWithAlphaSuccessMs);
  statistics->AddHistogram(kImageWebpWithAlphaFailureMs);

  statistics->AddVariable(kImageWebpOpaqueTimeouts);
  statistics->AddHistogram(kImageWebpOpaqueSuccessMs);
  statistics->AddHistogram(kImageWebpOpaqueFailureMs);
}

void ImageRewriteFilter::Initialize() {
  CHECK(related_options_ == NULL);
  related_options_ = new StringPieceVector;
  ImageRewriteFilter::AddRelatedOptions(ImageRewriteFilter::related_options_);
  std::sort(related_options_->begin(), related_options_->end());
}

void ImageRewriteFilter::Terminate() {
  CHECK(related_options_ != NULL);
  delete related_options_;
  related_options_ = NULL;
}

void ImageRewriteFilter::AddRelatedOptions(StringPieceVector* target) {
  for (int i = 0, n = arraysize(kRelatedOptions); i < n; ++i) {
    target->push_back(kRelatedOptions[i]);
  }
}

void ImageRewriteFilter::StartDocumentImpl() {
  image_counter_ = 0;
  saw_end_document_ = false;
  inlinable_urls_.clear();
  driver()->log_record()->LogRewriterHtmlStatus(
      RewriteOptions::kImageCompressionId, RewriterHtmlApplication::ACTIVE);
}

void ImageRewriteFilter::EndDocument() {
  saw_end_document_  = true;
}

void ImageRewriteFilter::RenderDone() {
  // Only care about the very end, not every flush window; framework orders
  // EndDocument before the last RenderDone (and after previous ones) so we
  // use EndDocument() having been called to distinguish the last flush window
  // from previous ones.
  if (!saw_end_document_) {
    return;
  }
  if (!image_info_.empty()) {
    GoogleString code =
        "psMobStaticImageInfo = {";
    for (AssociatedImageInfoMap::iterator i = image_info_.begin(),
                                          e = image_info_.end();
         i != e; ++i) {
      const AssociatedImageInfo& image_info = i->second;
      EscapeToJsStringLiteral(image_info.url(), true /* want quotes */,
                              &code);
      StrAppend(&code, ":{");
      StrAppend(&code, "w:",
                IntegerToString(image_info.dimensions().width()), ",");
      StrAppend(&code, "h:",
                IntegerToString(image_info.dimensions().height()), "},");
    }
    StrAppend(&code, "}");
    HtmlElement* script = driver()->NewElement(NULL, HtmlName::kScript);
    HtmlCharactersNode* chars = driver()->NewCharactersNode(script, code);
    InsertNodeAtBodyEnd(script);
    driver()->AppendChild(script, chars);
  }
  image_info_.clear();
}

// Allocate and initialize CompressionOptions object based on RewriteOptions and
// ResourceContext.
Image::CompressionOptions* ImageRewriteFilter::ImageOptionsForLoadedResource(
    const ResourceContext& resource_context,
    const ResourcePtr& input_resource) {
  Image::CompressionOptions* image_options = new Image::CompressionOptions();
  int64 input_size =
      static_cast<int64>(input_resource->UncompressedContentsSize());
  // Disable webp conversion for images in CSS if the original image size is
  // greater than max_image_bytes_in_css_for_webp. This is because webp does not
  // support progressive which causes a perceptible delay in the loading of
  // large background images.
  const RewriteOptions* options = driver()->options();
  if (resource_context.libwebp_level() != ResourceContext::LIBWEBP_NONE) {
    SetWebpCompressionOptions(resource_context, *options, input_resource->url(),
                              &webp_conversion_variables_, image_options);
  }

  DetermineQualities(*options, resource_context,
                     *driver()->request_properties(), image_options);

  image_options->progressive_jpeg =
      options->Enabled(RewriteOptions::kConvertJpegToProgressive) &&
      input_size >= options->progressive_jpeg_min_bytes();
  image_options->progressive_jpeg_min_bytes =
      options->progressive_jpeg_min_bytes();
  image_options->convert_png_to_jpeg =
      options->Enabled(RewriteOptions::kConvertPngToJpeg);
  image_options->convert_gif_to_png =
      options->Enabled(RewriteOptions::kConvertGifToPng);
  image_options->convert_jpeg_to_webp =
      options->Enabled(RewriteOptions::kConvertJpegToWebp);
  image_options->recompress_jpeg =
      options->Enabled(RewriteOptions::kRecompressJpeg);
  image_options->recompress_png =
      options->Enabled(RewriteOptions::kRecompressPng);
  image_options->recompress_webp =
      options->Enabled(RewriteOptions::kRecompressWebp);
  image_options->retain_color_profile =
      !options->Enabled(RewriteOptions::kStripImageColorProfile);
  image_options->retain_exif_data =
      !options->Enabled(RewriteOptions::kStripImageMetaData);
  image_options->retain_color_sampling =
      !options->Enabled(RewriteOptions::kJpegSubsampling);
  image_options->webp_conversion_timeout_ms =
      options->image_webp_timeout_ms();

  return image_options;
}

// Resize image if necessary, returning true if this resizing succeeds and false
// if it's unnecessary or fails.
bool ImageRewriteFilter::ResizeImageIfNecessary(
    const RewriteContext* rewrite_context, const GoogleString& url,
    ResourceContext* resource_context, Image* image, CachedResult* cached) {
  bool resized = false;
  // Begin by resizing the image if necessary
  ImageDim image_dim;
  image->Dimensions(&image_dim);

  if (image_dim.width() <= 0 || image_dim.height() <= 0) {
    cached->add_debug_message("Cannot resize: Image must be at least 1x1");
    return false;
  }

  // Here we are computing the size of the image as described by the html on the
  // page or as desired by mobile screen resolutions. If we succeed in doing so,
  // that will be the desired image size. Otherwise we may fill in
  // desired_image_dims later based on actual image size.
  ImageDim* desired_dim = resource_context->mutable_desired_image_dims();
  const ImageDim* post_resize_dim = &image_dim;
  if (ShouldResize(*resource_context, url, image, desired_dim)) {
    DCHECK_LT(0, desired_dim->width());
    DCHECK_LT(0, desired_dim->height());

    const char* message;  // Informational message for logging only.
    if (image->ResizeTo(*desired_dim)) {
      post_resize_dim = desired_dim;
      message = "Resized";
      resized = true;
    } else {
      message = "Couldn't resize";
    }

    driver()->InfoAt(rewrite_context, "%s image `%s' from %dx%d to %dx%d",
                     message, url.c_str(),
                     image_dim.width(), image_dim.height(),
                     desired_dim->width(), desired_dim->height());
    cached->add_debug_message(image->resize_debug_message());
  } else {
    cached->add_debug_message("Image does not appear to need resizing.");
  }

  // Cache image dimensions, including any resizing we did.
  // This happens regardless of whether we rewrite the image contents.
  if (ImageUrlEncoder::HasValidDimensions(*post_resize_dim)) {
    ImageDim* dims = cached->mutable_image_file_dims();
    dims->set_width(post_resize_dim->width());
    dims->set_height(post_resize_dim->height());
  }
  return resized;
}

// Determines whether an image should be resized based on the current options.
//
// Returns the dimensions to resize to in *desired_dimensions.
bool ImageRewriteFilter::ShouldResize(const ResourceContext& resource_context,
                                      const GoogleString& url,
                                      Image* image,
                                      ImageDim* desired_dim) {
  const RewriteOptions* options = driver()->options();
  if (!options->Enabled(RewriteOptions::kResizeImages) &&
      !options->Enabled(RewriteOptions::kResizeToRenderedImageDimensions)) {
    return false;
  }

  if (image->content_type()->type() != ContentType::kGif ||
      options->Enabled(RewriteOptions::kConvertGifToPng) ||
      options->Enabled(RewriteOptions::kDelayImages)) {
    *desired_dim = resource_context.desired_image_dims();
    ImageDim image_dim;
    image->Dimensions(&image_dim);
    if (options->Enabled(RewriteOptions::kResizeToRenderedImageDimensions)) {
      // Respect the aspect ratio of the image when doing the resize.
      SetDesiredDimensionsIfRequired(desired_dim, image_dim);
    } else {
      UpdateDesiredImageDimsIfNecessary(
          image_dim, resource_context, desired_dim);
      if (options->Enabled(RewriteOptions::kResizeImages) &&
          ImageUrlEncoder::HasValidDimension(*desired_dim) &&
          ImageUrlEncoder::HasValidDimensions(image_dim)) {
        SetDesiredDimensionsIfRequired(desired_dim, image_dim);
      }
    }
    if (ImageUrlEncoder::HasValidDimension(*desired_dim) &&
        ImageUrlEncoder::HasValidDimensions(image_dim)) {
      const int64 page_area =
          static_cast<int64>(desired_dim->width()) *
          desired_dim->height();
      const int64 image_area =
          static_cast<int64>(image_dim.width()) * image_dim.height();
      if (page_area * 100 <
          image_area * options->image_limit_resize_area_percent()) {
        DCHECK_LT(0, desired_dim->width());
        DCHECK_LT(0, desired_dim->height());
        return true;
      }
    }
  }
  return false;
}

namespace {

int64 GetCurrentCpuTimeMs(Timer* timer) {
  // See http://linux.die.net/man/2/getrusage -- RUSAGE_THREAD is supported
  // on Linux since Linux 2.6.26, so fall back to wall-clock time.
#ifdef RUSAGE_THREAD
  struct rusage start_rusage;
  if (getrusage(RUSAGE_THREAD, &start_rusage) == 0) {
    return ((start_rusage.ru_utime.tv_sec * 1000) +
            (start_rusage.ru_utime.tv_usec / 1000));
  }
#endif
  return timer->NowMs();
}

}  // namespace

// Format as InfoAt and using TracePrintf.
// TODO(jmaessen): Avoid formatting if neither applies.
void ImageRewriteFilter::InfoAndTrace(
    Context* rewrite_context, const char* format, ...) {
  va_list args;
  va_start(args, format);
  GoogleString message;
  StringAppendV(&message, format, args);
  driver()->InfoAt(rewrite_context, "%s", message.c_str());
  driver()->TraceString(message);
  va_end(args);
}

RewriteResult ImageRewriteFilter::RewriteLoadedResourceImpl(
      Context* rewrite_context, const ResourcePtr& input_resource,
      const OutputResourcePtr& result) {
  rewrite_context->TracePrintf("Image rewrite: %s",
                               input_resource->url().c_str());
  MessageHandler* message_handler = driver()->message_handler();
  StringVector urls;
  ResourceContext resource_context;
  const RewriteOptions* options = driver()->options();

  resource_context = *rewrite_context->resource_context();

  if (!encoder_.Decode(result->name(),
                       &urls, &resource_context, message_handler)) {
    image_rewrites_dropped_intentionally_->Add(1);
    image_rewrites_dropped_decode_failure_->Add(1);
    return kRewriteFailed;
  }

  Image::CompressionOptions* image_options =
      ImageOptionsForLoadedResource(resource_context, input_resource);
  scoped_ptr<Image> image(
      NewImage(input_resource->ExtractUncompressedContents(),
               input_resource->url(), server_context()->filename_prefix(),
               image_options, driver()->timer(), message_handler));

  // Initialize logging data.
  ImageType original_image_type = image->image_type();
  ImageType optimized_image_type = original_image_type;
  int original_size = image->input_size();
  int optimized_size = original_size;
  bool is_recompressed = false;
  bool is_resized = false;

  if (original_image_type == IMAGE_UNKNOWN) {
    image_rewrites_dropped_intentionally_->Add(1);
    image_rewrites_dropped_mime_type_unknown_->Add(1);
    driver()->InfoAt(
        rewrite_context, "%s: Image MIME type could not be "
        "discovered from reading magic bytes; rewriting dropped.",
        input_resource->url().c_str());
    return kRewriteFailed;
  }
  // We used to reject beacon images based on their size (1x1 or less) here, but
  // now rely on caching headers instead as this was missing a lot of padding
  // images that were ripe for inlining.
  RewriteResult rewrite_result = kTooBusy;

  ImageDim image_dim;
  image->Dimensions(&image_dim);
  int64 image_width = image_dim.width(), image_height = image_dim.height();
  if ((image_width*image_height*4) > options->image_resolution_limit_bytes()) {
    image_rewrites_dropped_intentionally_->Add(1);
    image_norewrites_high_resolution_->Add(1);
    return kRewriteFailed;
  }

  image_ongoing_rewrites_->Add(1);

  rewrite_result = kRewriteFailed;
  Timer* timer = server_context()->timer();
  int64 rewrite_time_start_ms = GetCurrentCpuTimeMs(timer);
  CachedResult* cached = result->EnsureCachedResultCreated();
  is_resized = ResizeImageIfNecessary(
      rewrite_context, input_resource->url(),
      &resource_context, image.get(), cached);

  // When the "resize_images" filter has been turned on and the IMG tag has
  // width and/or height specified, we assume that the image will be resized so
  // the new dimension will be embedded into the rewritten image URL. However,
  // if reizing turns out to be a failure, we don't want the new dimension in
  // the rewritten URL. For the latter case, we will reset the "name" of the
  // output resource.
  if (!is_resized) {
    resource_context.clear_desired_image_dims();
    GoogleString name;
    GoogleUrl mapped_gurl;  // Not used
    GoogleString failure_reason;  // Not used
    if (driver()->GenerateOutputResourceNameAndUrl(
            encoder(), &resource_context, input_resource, &name, &mapped_gurl,
            &failure_reason)) {
      result->mutable_full_name()->set_name(name);
    } else {
      LOG(DFATAL) << "Failed to generate name and URL for the output resource.";
      return kRewriteFailed;
    }
  }

  // Now re-compress the (possibly resized) image, and decide if it's
  // saved us anything.
  if (is_resized || options->ImageOptimizationEnabled()) {
  // Call output_size() before image_type(). When output_size() is called,
    // the image will be recompressed and the image type may be changed
    // in order to get the smallest output.
    optimized_size = image->output_size();
    optimized_image_type = image->image_type();
    is_recompressed = true;

    // The image has been recompressed (and potentially resized). However,
    // the recompressed image may not be used unless the file size is reduced.
    if (image->output_size() * 100 <
        image->input_size() * options->image_limit_optimized_percent()) {
      // Here output image type could potentially be different from input
      // type.
      const ContentType* output_type =
          ImageToContentType(input_resource->url(), image.get());

      // Consider inlining output image (no need to check input, it's bigger)
      // This needs to happen before Write to persist.
      SaveIfInlinable(image->Contents(), image->image_type(), cached);

      server_context()->MergeNonCachingResponseHeaders(
          input_resource, result);
      if (options->no_transform_optimized_images()) {
        result->set_cache_control_suffix(",no-transform");
      }
      if (driver()->Write(
              ResourceVector(1, input_resource), image->Contents(),
              output_type, StringPiece() /* no charset for images */,
              result.get())) {
        driver()->InfoAt(
            rewrite_context,
            "Shrinking image `%s' (%u bytes) to `%s' (%u bytes)",
            input_resource->url().c_str(),
            static_cast<unsigned>(image->input_size()),
            result->url().c_str(),
            static_cast<unsigned>(image->output_size()));

        // Update stats.
        image_rewrites_->Add(1);
        image_rewrite_total_bytes_saved_->Add(
            image->input_size() - image->output_size());
        image_rewrite_total_original_bytes_->Add(image->input_size());
        if (result->type()->type() == ContentType::kWebp) {
          image_webp_rewrites_->Add(1);
        }

        rewrite_result = kRewriteOk;
      } else {
        // Server fails to write merged files.
        image_rewrites_dropped_server_write_fail_->Add(1);
        InfoAndTrace(
            rewrite_context,
            "Server fails writing image content for `%s'; rewriting dropped.",
            input_resource->url().c_str());
      }
    } else if (is_resized) {
      // Eliminate any image dimensions from a resize operation that
      // succeeded, but yielded overly-large output.
      image_rewrites_dropped_nosaving_resize_->Add(1);
      InfoAndTrace(
          rewrite_context,
          "Shrink of image `%s' (%u -> %u bytes) doesn't save space; "
          "dropped.",
          input_resource->url().c_str(),
          static_cast<unsigned>(image->input_size()),
          static_cast<unsigned>(image->output_size()));
      ImageDim* dims = cached->mutable_image_file_dims();
      dims->clear_width();
      dims->clear_height();
    } else if (options->ImageOptimizationEnabled()) {
      // Fails due to overly-large output without resize.
      image_rewrites_dropped_nosaving_noresize_->Add(1);
      InfoAndTrace(
          rewrite_context,
          "Recompressing image `%s' (%u -> %u bytes) doesn't save space; "
          "dropped.",
          input_resource->url().c_str(),
          static_cast<unsigned>(image->input_size()),
          static_cast<unsigned>(image->output_size()));
    }
  }

  cached->set_optimized_image_type(optimized_image_type);
  cached->set_size(rewrite_result == kRewriteOk ? image->output_size() :
                   image->input_size());
  SaveDebugMessageToCache(image->debug_message(), rewrite_context, cached);

  // Try inlining input image if output hasn't been inlined already.
  if (!cached->has_inlined_data()) {
    SaveIfInlinable(input_resource->ExtractUncompressedContents(),
                    original_image_type, cached);
  }

  int64 image_size = static_cast<int64>(image->output_size());
  if (options->Enabled(RewriteOptions::kDelayImages) &&
      !rewrite_context->in_noscript_element_ &&
      !cached->has_low_resolution_inlined_data() &&
      image_size >= options->min_image_size_low_resolution_bytes() &&
      image_size <= options->max_image_size_low_resolution_bytes()) {
    Image::CompressionOptions* image_options =
        new Image::CompressionOptions();
    SetWebpCompressionOptions(resource_context, *options,
                              input_resource->url(),
                              &webp_conversion_variables_,
                              image_options);

    image_options->jpeg_quality = options->ImageJpegQuality();
    image_options->webp_quality = options->ImageWebpQuality();
    image_options->webp_animated_quality = options->ImageWebpAnimatedQuality();
    image_options->progressive_jpeg = false;
    image_options->convert_png_to_jpeg =
        options->Enabled(RewriteOptions::kConvertPngToJpeg);

    // Set to true since we optimize a gif to png before resize.
    image_options->convert_gif_to_png = true;
    image_options->recompress_jpeg = true;
    image_options->recompress_png = true;
    image_options->recompress_webp = true;

    // Since these are replaced with their high res versions, stripping
    // them off for low res images will further reduce bytes.
    image_options->retain_color_profile = false;
    image_options->retain_exif_data = false;
    image_options->retain_color_sampling = false;
    image_options->jpeg_num_progressive_scans =
        options->image_jpeg_num_progressive_scans();

    scoped_ptr<Image> low_image;
    if (driver()->options()->use_blank_image_for_inline_preview()) {
      image_options->use_transparent_for_blank_image = true;
      low_image.reset(BlankImageWithOptions(image_width, image_height,
          IMAGE_PNG, server_context()->filename_prefix(),
          timer, message_handler, image_options));
      low_image->EnsureLoaded(true);
    } else {
      low_image.reset(NewImage(image->Contents(), input_resource->url(),
          server_context()->filename_prefix(), image_options,
          timer, message_handler));
    }
    low_image->SetTransformToLowRes();
    if (ShouldInlinePreview(low_image->Contents().size(),
                            image->Contents().size(), options)) {
      if (resource_context.mobile_user_agent()) {
        ResizeLowQualityImage(low_image.get(), input_resource, cached);
      } else {
        cached->set_low_resolution_inlined_data(low_image->Contents().data(),
                                                low_image->Contents().size());
      }
      cached->set_low_resolution_inlined_image_type(
          static_cast<int>(low_image->image_type()));
    }
  }
  image_ongoing_rewrites_->Add(-1);

  int64 latency_ms = GetCurrentCpuTimeMs(timer) - rewrite_time_start_ms;
  if (rewrite_result == kRewriteOk) {
    image_rewrite_latency_ok_ms_->Add(latency_ms);
  } else {
    image_rewrite_latency_failed_ms_->Add(latency_ms);
  }

  // We track the total latency (including failed & OK) in its own
  // variable so it can be easily scraped with wget.  The ok/failed
  // versions above are histograms and thus harder to scrape.
  image_rewrite_latency_total_ms_->Add(latency_ms);

  // All other conditions were updated in other code paths above.
  if (rewrite_result == kRewriteFailed) {
    image_rewrites_dropped_intentionally_->Add(1);
  } else if (rewrite_result == kRewriteOk) {
    rewrite_context->TracePrintf("Image rewrite success (%u -> %u)",
                                 static_cast<unsigned>(image->input_size()),
                                 static_cast<unsigned>(image->output_size()));
  }

  const ImageDim& post_resize_dim =
      resource_context.desired_image_dims();
  LogImageBackgroundRewriteActivity(driver(),
      rewrite_result == kRewriteOk ?
          RewriterApplication::APPLIED_OK : RewriterApplication::NOT_APPLIED,
      input_resource->url(), LoggingId(), original_size, optimized_size,
      is_recompressed, original_image_type, optimized_image_type, is_resized,
      image_width, image_height,
      rewrite_context->is_resized_using_rendered_dimensions_,
      post_resize_dim.width(), post_resize_dim.height());

  return rewrite_result;
}

// Generate resized low quality image if the image width is not smaller than
// kDelayImageWidthForMobile. If image width is smaller than
// kDelayImageWidthForMobile, "delay_images" optimization is not very useful
// and no low quality image will be generated.
void ImageRewriteFilter::ResizeLowQualityImage(
    Image* low_image, const ResourcePtr& input_resource, CachedResult* cached) {
  ImageDim image_dim;
  low_image->Dimensions(&image_dim);
  if (image_dim.width() >= kDelayImageWidthForMobile) {
    const RewriteOptions* options = driver()->options();
    Image::CompressionOptions* image_options =
        new Image::CompressionOptions();
    image_options->jpeg_quality = options->ImageJpegQuality();
    image_options->webp_quality = options->ImageWebpQuality();
    image_options->webp_animated_quality = options->ImageWebpAnimatedQuality();
    image_options->progressive_jpeg = false;
    image_options->convert_png_to_jpeg =
        options->Enabled(RewriteOptions::kConvertPngToJpeg);
    image_options->convert_gif_to_png =
        options->Enabled(RewriteOptions::kConvertGifToPng);
    image_options->recompress_jpeg =
        options->Enabled(RewriteOptions::kRecompressJpeg);
    image_options->recompress_png =
        options->Enabled(RewriteOptions::kRecompressPng);
    image_options->recompress_webp =
        options->Enabled(RewriteOptions::kRecompressWebp);
    scoped_ptr<Image> image(
        NewImage(low_image->Contents(), input_resource->url(),
                 server_context()->filename_prefix(), image_options,
                 driver()->timer(), driver()->message_handler()));
    image->SetTransformToLowRes();
    ImageDim resized_dim;
    resized_dim.set_width(kDelayImageWidthForMobile);
    resized_dim.set_height((static_cast<int64>(resized_dim.width()) *
                            image_dim.height()) / image_dim.width());
    MessageHandler* message_handler = driver()->message_handler();
    bool resized = image->ResizeTo(resized_dim);
    StringPiece contents = image->Contents();
    StringPiece old_contents = low_image->Contents();
    if (resized && contents.size() < old_contents.size()) {
      cached->set_low_resolution_inlined_data(contents.data(), contents.size());
      message_handler->Message(
          kInfo,
          "Resized low quality image (%s) from "
          "%dx%d(%d bytes) to %dx%d(%d bytes)",
          input_resource->url().c_str(),
          image_dim.width(), image_dim.height(),
          static_cast<int>(old_contents.size()),
          resized_dim.width(), resized_dim.width(),
          static_cast<int>(contents.size()));
    } else {
      message_handler->Message(
          kInfo,
          "Couldn't resize low quality image (%s) or resized image file is "
          "not smaller: "
          "%dx%d(%d bytes) => %dx%d(%d bytes)",
          input_resource->url().c_str(),
          image_dim.width(), image_dim.height(),
          static_cast<int>(old_contents.size()),
          resized_dim.width(), resized_dim.height(),
          static_cast<int>(contents.size()));
    }
  }
}

void ImageRewriteFilter::SaveIfInlinable(const StringPiece& contents,
                                         const ImageType image_type,
                                         CachedResult* cached) {
  // We retain inlining information if the image size is < the largest possible
  // inlining threshold, as an image might be used in both html and css and we
  // may see it first from the one with a smaller threshold. Note that this can
  // cause us to save inline information for an image that won't ever actually
  // be inlined (because it's too big to inline in html, say, and doesn't occur
  // in css).
  int64 image_inline_max_bytes =
      driver()->options()->MaxImageInlineMaxBytes();
  if (static_cast<int64>(contents.size()) < image_inline_max_bytes) {
    cached->set_inlined_data(contents.data(), contents.size());
    cached->set_inlined_image_type(static_cast<int>(image_type));
  }
}

// Convert (possibly NULL) Image* to corresponding (possibly NULL) ContentType*
const ContentType* ImageRewriteFilter::ImageToContentType(
    const GoogleString& origin_url, Image* image) {
  const ContentType* content_type = NULL;
  if (image != NULL) {
    // Even if we know the content type from the extension coming
    // in, the content-type can change as a result of compression,
    // e.g. gif to png, or jpeg to webp.
    return image->content_type();
  }
  return content_type;
}

void ImageRewriteFilter::BeginRewriteImageUrl(HtmlElement* element,
                                              HtmlElement::Attribute* src) {
  scoped_ptr<ResourceContext> resource_context(new ResourceContext);
  const RewriteOptions* options = driver()->options();
  bool is_resized_using_rendered_dimensions = false;

  // In case of RewriteOptions::image_preserve_urls() we do not want to use
  // image dimension information from HTML/CSS.

  if (options->Enabled(RewriteOptions::kResizeImages) ||
      options->Enabled(RewriteOptions::kResizeToRenderedImageDimensions)) {
    ImageDim* desired_dim = resource_context->mutable_desired_image_dims();
    GetDimensions(element, desired_dim, src,
                  &is_resized_using_rendered_dimensions);
    if ((desired_dim->width() == 0 || desired_dim->height() == 0 ||
         (desired_dim->width() == 1 && desired_dim->height() == 1))) {
      // This is either a beacon image, or an attempt to prefetch.  Drop the
      // desired dimensions so that the image is not resized.
      resource_context->clear_desired_image_dims();
    }
  }
  StringPiece url(src->DecodedValueOrNull());

  EncodeUserAgentIntoResourceContext(resource_context.get());

  ResourcePtr input_resource(CreateInputResourceOrInsertDebugComment(
      src->DecodedValueOrNull(), element));
  if (input_resource.get() == NULL) {
    return;
  }

  // If the image will be inlined and the local storage cache is enabled, add
  // the LSC marker attribute to this element so that the LSC filter knows to
  // insert the relevant javascript functions.
  if (driver()->request_properties()->SupportsImageInlining()) {
    LocalStorageCacheFilter::InlineState state;
    LocalStorageCacheFilter::AddStorableResource(src->DecodedValueOrNull(),
                                                 driver(),
                                                 true /* ignore cookie */,
                                                 element, &state);
  }
  Context* context = new Context(0 /* No CSS inlining, it's html */,
                                 this, driver(), NULL /*not nested */,
                                 resource_context.release(),
                                 false /*not css */, image_counter_++,
                                 noscript_element() != NULL,
                                 is_resized_using_rendered_dimensions);
  ResourceSlotPtr slot(driver()->GetSlot(input_resource, element, src));
  context->AddSlot(slot);

  // Note that in RewriteOptions::Merge we turn off image_preserve_urls
  // when merging into a configuration that has explicitly
  // enabled cache_extend_images.
  //
  // Consider a hosting provider that turns on "optimize for
  // bandwidth" mode, and then a site enables resize_images
  // explicitly.  That should override the image-url-preservation
  // default that was set at root.  Note that explicitly turning on
  // RecompressImages doesn't mean we'll want to override
  // image_preserve_urls rewrite URLs here, since we can still get
  // the benefit of recompression via IPRO.  But we make an
  // exception for inlining and image-resizing directives since
  // those can only be done via url-rewriting.
  if (options->image_preserve_urls() &&
      !options->Enabled(RewriteOptions::kResizeImages) &&
      !options->Enabled(RewriteOptions::kResizeToRenderedImageDimensions) &&
      !options->Enabled(RewriteOptions::kInlineImages)) {
    slot->set_preserve_urls(true);
  }
  driver()->InitiateRewrite(context);
}

bool ImageRewriteFilter::FinishRewriteCssImageUrl(
    int64 css_image_inline_max_bytes, const CachedResult* cached,
    ResourceSlot* slot, InlineResult* inline_result) {
  GoogleString data_url;
  *inline_result = TryInline(false /*not html*/, false /*not critical*/,
                             css_image_inline_max_bytes, cached, slot,
                             &data_url);

  if (*inline_result == INLINE_SUCCESS) {
    // TODO(jmaessen): Can we make output URL reflect actual *usage*
    // of image inlining and/or webp images?
    const RewriteOptions* options = driver()->options();
    DCHECK(!options->cache_small_images_unrewritten())
        << "Modifying a URL slot despite "
        << "image_inlining_identify_and_cache_without_rewriting set.";
    if (slot->DirectSetUrl(data_url)) {
      image_inline_count_->Add(1);
      return true;
    }
  } else if (cached->optimizable()) {
    image_rewrite_uses_->Add(1);
  }
  // Fall back to nested rewriting, which will also left trim the url if that
  // is required.
  return false;
}

namespace {

// Skip ascii whitespace, returning pointer to first non-whitespace character in
// accordance with:
//   http://www.whatwg.org/specs/web-apps/current-work/multipage/
//                  common-microsyntaxes.html#space-character
const char* SkipAsciiWhitespace(const char* position) {
  while (*position <= ' ' &&  // Quickly skip if no leading whitespace
         (*position == ' ' || *position == '\x09' || *position == '\x0A' ||
          *position == '\x0C' || *position == '\x0D')) {
    ++position;
  }
  return position;
}

bool GetDimensionAttribute(
    const HtmlElement* element, HtmlName::Keyword name, int* value) {
  const HtmlElement::Attribute* attribute = element->FindAttribute(name);
  if (attribute == NULL) {
    return false;
  }
  const char* position = attribute->DecodedValueOrNull();
  return ImageRewriteFilter::ParseDimensionAttribute(position, value);
}

// If the element has a width attribute, set it in page_dim.
void SetWidthFromAttribute(const HtmlElement* element, ImageDim* page_dim) {
  int32 width;
  if (GetDimensionAttribute(element, HtmlName::kWidth, &width)) {
    page_dim->set_width(width);
  }
}

// If the element has a height attribute, set it in page_dim.
void SetHeightFromAttribute(const HtmlElement* element, ImageDim* page_dim) {
  int32 height;
  if (GetDimensionAttribute(element, HtmlName::kHeight, &height)) {
    page_dim->set_height(height);
  }
}

void DeleteMatchingImageDimsAfterInline(
    const CachedResult* cached, HtmlElement* element) {
  // Never strip width= or height= attributes from non-img elements.
  if (element->keyword() != HtmlName::kImg) {
    return;
  }
  // We used to take the absence of desired_image_dims here as license to delete
  // dimensions.  That was incorrect, as sometimes there were dimensions in the
  // page but the image was being enlarged on page and we can't strip the
  // enlargement out safely.  Now we also strip desired_image_dims when the
  // image is 1x1 or less.  As a result, we go back to the html to determine
  // whether it's safe to strip the width and height attributes, doing so only
  // if all dimensions that are present match the actual post-optimization image
  // dimensions.
  if (cached->has_image_file_dims()) {
    int attribute_width, attribute_height = -1;
    if (GetDimensionAttribute(element, HtmlName::kWidth, &attribute_width)) {
      if (cached->image_file_dims().width() == attribute_width) {
        // Width matches, height must either be absent or match.
        if (!element->FindAttribute(HtmlName::kHeight)) {
          // No height, just delete width.
          element->DeleteAttribute(HtmlName::kWidth);
        } else if (GetDimensionAttribute(
                element, HtmlName::kHeight, &attribute_height) &&
            cached->image_file_dims().height() == attribute_height) {
          // Both dimensions match, delete both.
          element->DeleteAttribute(HtmlName::kWidth);
          element->DeleteAttribute(HtmlName::kHeight);
        }
      }
    } else if (!element->FindAttribute(HtmlName::kWidth) &&
        GetDimensionAttribute(element, HtmlName::kHeight, &attribute_height) &&
        cached->image_file_dims().height() == attribute_height) {
      // No width, matching height
      element->DeleteAttribute(HtmlName::kHeight);
    }
  }
}

}  // namespace

bool ImageRewriteFilter::FinishRewriteImageUrl(
    const CachedResult* cached, const ResourceContext* resource_context,
    HtmlElement* element, HtmlElement::Attribute* src, int image_index,
    HtmlResourceSlot* slot, InlineResult* inline_result) {
  GoogleString src_value(src->DecodedValueOrNull());
  if (src_value.empty()) {
    return false;
  }

  const RewriteOptions* options = driver()->options();
  bool rewrote_url = false;
  bool image_inlined = false;
  const bool is_critical_image = IsHtmlCriticalImage(src_value);

  // Don't inline images used by responsive filter (except for the ones
  // explicitly marked as inlinable).
  const char* responsive_attr =
      element->AttributeValue(HtmlName::kDataPagespeedResponsiveTemp);
  if (responsive_attr != NULL &&
      StringPiece(responsive_attr) !=
      ResponsiveImageFirstFilter::kInlinableVirtualImage) {
    *inline_result = INLINE_RESPONSIVE;
  } else if (element->keyword() == HtmlName::kLink) {
    // Don't inline shortcut images.  All shortcut images are on link tags, and
    // no non-shortcut images are on link tags, so we can just check if this is
    // a link tag.  This is to exclude inlining on:
    // * <link rel=icon ...>
    // * <link rel=apple-touch-icon ...>
    // * <link rel=apple-touch-icon-precomposed ...>
    // * <link rel=apple-touch-startup-image ...>
    *inline_result = INLINE_SHORTCUT;
  } else {
    // See if we have a data URL, and if so use it if the browser can handle it
    // TODO(jmaessen): get rid of a string copy here. Tricky because
    // src->SetValue() copies implicitly.
    GoogleString data_url;
    // TODO(sligocki): Use different threshold for responsive images?
    *inline_result = TryInline(true /*in html*/, is_critical_image,
                               options->ImageInlineMaxBytes(),
                               cached, slot, &data_url);

    if (*inline_result == INLINE_SUCCESS) {
      DCHECK(!options->cache_small_images_unrewritten())
          << "Modifying a URL slot despite "
          << "image_inlining_identify_and_cache_without_rewriting set.";
      src->SetValue(data_url);
      // Note the use of the ORIGINAL url not the data url.
      LocalStorageCacheFilter::AddLscAttributes(src_value, *cached,
                                                driver(), element);
      // AddLscAttributes uses the width and height attributes so must be called
      // before we delete them with:
      DeleteMatchingImageDimsAfterInline(cached, element);
      image_inline_count_->Add(1);
      rewrote_url = true;
      image_inlined = true;
    }
  }

  // Rewrite URL in case this image was not inlined (and URL rewriting allowed).
  if (!image_inlined && !slot->preserve_urls()) {
    // Not inlined means we cannot store it in local storage.
    LocalStorageCacheFilter::RemoveLscAttributes(element, driver());
    if (cached->optimizable()) {
      // Rewritten HTTP url
      src->SetValue(ResourceSlot::RelativizeOrPassthrough(
          options, cached->url(), slot->url_relativity(),
          driver()->base_url()));
      image_rewrite_uses_->Add(1);
      rewrote_url = true;
    }
    if (options->Enabled(RewriteOptions::kInsertImageDimensions) &&
        (element->keyword() == HtmlName::kImg ||
         element->keyword() == HtmlName::kInput) &&
        !HasAnyDimensions(element) &&
        cached->has_image_file_dims() &&
        ImageUrlEncoder::HasValidDimensions(cached->image_file_dims())) {
      // Add image dimensions. We don't bother to resize if either dimension is
      // specified with units (em, %) rather than as absolute pixels. But note
      // that we DO attempt to include image dimensions even if we otherwise
      // choose not to optimize an image.
      const ImageDim& file_dims = cached->image_file_dims();
      driver()->AddAttribute(element, HtmlName::kWidth,
                             IntegerToString(file_dims.width()));
      driver()->AddAttribute(element, HtmlName::kHeight,
                             IntegerToString(file_dims.height()));
    }
    if (element->FindAttribute(HtmlName::kDataPagespeedResponsiveTemp) != NULL
        && cached->has_image_file_dims()
        && ImageUrlEncoder::HasValidDimensions(cached->image_file_dims())) {
      // If this is an image used by ResponsiveImageFilter, add information
      // on actual final dimensions used. That way we can decide which to use
      // in srcset and which to discard (because they are the same size as a
      // lower density image).
      const ImageDim& file_dims = cached->image_file_dims();
      driver()->AddAttribute(element, HtmlName::kDataActualWidth,
                             IntegerToString(file_dims.width()));
      driver()->AddAttribute(element, HtmlName::kDataActualHeight,
                             IntegerToString(file_dims.height()));
    }
  }

  bool low_res_src_inserted = false;
  bool try_low_res_src_insertion = false;
  ImageType low_res_image_type = IMAGE_UNKNOWN;
  if (options->Enabled(RewriteOptions::kDelayImages) &&
      src->keyword() == HtmlName::kSrc &&
      (element->keyword() == HtmlName::kImg ||
       element->keyword() == HtmlName::kInput)) {
    try_low_res_src_insertion = true;
    int max_preview_image_index = options->max_inlined_preview_images_index();
    if (!image_inlined &&
        !slot->preserve_urls() &&
        is_critical_image &&
        driver()->request_properties()->SupportsImageInlining() &&
        driver()->server_context()->critical_images_finder()->Available(
            driver()) != CriticalImagesFinder::kNoDataYet &&
        cached->has_low_resolution_inlined_data() &&
        (max_preview_image_index < 0 ||
         image_index < max_preview_image_index)) {
      low_res_image_type = static_cast<ImageType>(
          cached->low_resolution_inlined_image_type());

      const ContentType* content_type =
          Image::TypeToContentType(low_res_image_type);
      DCHECK(content_type != NULL) << "Invalid Image Type: "
                                   << low_res_image_type;
      if (content_type != NULL) {
        GoogleString data_url;
        DataUrl(*content_type, BASE64, cached->low_resolution_inlined_data(),
                &data_url);
        driver()->AddAttribute(
            element, HtmlName::kDataPagespeedLowResSrc, data_url);
        driver()->increment_num_inline_preview_images();
        low_res_src_inserted = true;
      } else {
        driver()->message_handler()->Message(kError,
                                             "Invalid low res image type: %d",
                                             low_res_image_type);
      }
    }
  }

  // Absolutify the image url for logging.
  GoogleUrl image_gurl(driver()->base_url(), src_value);
  driver()->log_record()->LogImageRewriteActivity(
      LoggingId(),
      image_gurl.spec_c_str(),
      (rewrote_url ?
       RewriterApplication::APPLIED_OK :
       RewriterApplication::NOT_APPLIED),
      image_inlined,
      is_critical_image,
      cached->optimizable(),
      cached->size(),
      try_low_res_src_insertion,
      low_res_src_inserted,
      low_res_image_type,
      cached->low_resolution_inlined_data().size());
  return rewrote_url;
}

void ImageRewriteFilter::SaveDebugMessageToCache(const GoogleString& message,
                                                 Context* rewrite_context,
                                                 CachedResult* cached_result) {
  if (!message.empty()) {
    // We always save our result to our cache entry, since it will be propagated
    // to the parent automatically, and we need to be replayable independently.
    cached_result->add_debug_message(message);
  }
}

bool ImageRewriteFilter::IsHtmlCriticalImage(StringPiece image_url) const {
  CriticalImagesFinder* finder =
      driver()->server_context()->critical_images_finder();
  if (finder->Available(driver()) != CriticalImagesFinder::kAvailable) {
    // Default to all images being critical if we don't have meaningful critical
    // image information.
    return true;
  }
  GoogleUrl image_gurl(driver()->base_url(), image_url);
  return finder->IsHtmlCriticalImage(image_gurl.Spec(), driver());
}

bool ImageRewriteFilter::StoreUrlInPropertyCache(const StringPiece& url) {
  if (url.length() == 0) {
    return true;
  }
  PropertyPage* property_page = driver()->property_page();
  if (property_page == NULL) {
    LOG(WARNING) << "image_inlining_identify_and_cache_without_rewriting "
                 << "without PropertyPage.";
    return false;
  }
  const PropertyCache::Cohort* cohort =
      driver()->server_context()->dom_cohort();
  if (cohort == NULL) {
    LOG(WARNING) << "image_inlining_identify_and_cache_without_rewriting "
                 << "without configured DOM cohort.";
    return false;
  }
  PropertyValue* value = property_page->GetProperty(
      cohort, kInlinableImageUrlsPropertyName);
  VLOG(3) << "image_inlining_identify_and_cache_without_rewriting value "
          << "inserted into pcache: " << url;
  GoogleString new_value(StrCat("\"", url, "\""));
  if (value->has_value()) {
    StrAppend(&new_value, ",", value->value());
  }
  property_page->UpdateValue(
      cohort, kInlinableImageUrlsPropertyName, new_value);
  return true;
}

bool ImageRewriteFilter::HasAnyDimensions(HtmlElement* element) {
  if (element->FindAttribute(HtmlName::kWidth)) {
    return true;
  }
  if (element->FindAttribute(HtmlName::kHeight)) {
    return true;
  }
  css_util::StyleExtractor extractor(element);
  return extractor.HasAnyDimensions();
}

bool ImageRewriteFilter::ParseDimensionAttribute(
    const char* position, int* value) {
  if (position == NULL) {
    return false;
  }
  // Note that we rely heavily on null-termination of char* here to cause our
  // control flow to fall through when we reach end of string.  Numbered steps
  // correspond to the steps in the spec.
  //   http://www.whatwg.org/specs/web-apps/current-work/multipage/
  //                  common-microsyntaxes.html#percentages-and-dimensions
  // 3) Skip ascii whitespace
  position = SkipAsciiWhitespace(position);
  // 5) Skip leading plus
  if (*position == '+') {
    ++position;
  }
  unsigned int result = 0;  // unsigned for consistent overflow behavior.
  // 6,7,9) Process digits
  while ('0' <= *position && *position <= '9') {
    unsigned int new_result = result * 10 + *position - '0';
    if (new_result < result) {
      // Integer overflow.  Reject.
      return false;
    }
    result = new_result;
    ++position;
  }
  // 6,7,8) Reject if no digits or only zeroes, or conversion to signed will
  // fail.
  if (result < 1 || INT_MAX < result) {
    return false;
  }
  // 11) Process fraction (including 45. with nothing after the . )
  if (*position == '.') {
    ++position;
    if ('5' <= *position && *position <= '9' && result < INT_MAX) {
      // Round based on leading fraction digit, avoiding overflow.
      ++result;
      ++position;
    }
    // Discard all fraction digits.
    while ('0' <= *position && *position <= '9') {
      ++position;
    }
  }
  // Skip whitespace before a possible trailing px.  The spec allows other junk,
  // or a trailing percent, but we can't resize percentages and older browsers
  // don't resize when they encounter junk.
  position = SkipAsciiWhitespace(position);
  if (position[0] == 'p' && position[1] == 'x') {
    position = SkipAsciiWhitespace(position + 2);
  }
  // Reject if there's trailing junk.
  if (*position != '\0') {
    return false;
  }
  // 14) return result as length.
  *value = static_cast<int>(result);
  return true;
}

void ImageRewriteFilter::GetDimensions(
    HtmlElement* element,
    ImageDim* page_dim,
    const HtmlElement::Attribute* src,
    bool* is_resized_using_rendered_dimensions) {
  css_util::StyleExtractor extractor(element);
  css_util::DimensionState state = extractor.state();
  int32 width = extractor.width();
  int32 height = extractor.height();
  int32 rendered_width = 0;
  int32 rendered_height = 0;
  // If the image has rendered dimensions stored in the property cache, update
  // the desired image dimensions. Don't use rendered image dimensions
  // when beaconing, since it would cause improper instrumentation.
  if (driver()->options()->Enabled(
          RewriteOptions::kResizeToRenderedImageDimensions) &&
      !CriticalImagesBeaconFilter::ShouldApply(driver())) {
    StringPiece src_value(src->DecodedValueOrNull());
    if (!src_value.empty()) {
      GoogleUrl src_gurl(driver()->base_url(), src_value);
      if (src_gurl.IsWebOrDataValid()) {
        std::pair<int32, int32> dimensions;
        CriticalImagesFinder* finder =
            driver()->server_context()->critical_images_finder();
        if (finder->GetRenderedImageDimensions(
                driver(), src_gurl, &dimensions)) {
          if (dimensions.first != 0 && dimensions.second != 0) {
            rendered_width = dimensions.first;
            rendered_height = dimensions.second;
          }
        }
      }
    }
  }
  // If we didn't get a height dimension above, but there is a height
  // value in the style attribute, that means there's a height value
  // we can't process. This height will trump the height attribute in the
  // image tag, so we need to avoid resizing.
  // The same is true of width.
  switch (state) {
    case css_util::kNotParsable:
      break;
    case css_util::kHasBothDimensions:
      page_dim->set_width(width);
      page_dim->set_height(height);
      break;
    case css_util::kHasHeightOnly:
      page_dim->set_height(height);
      SetWidthFromAttribute(element, page_dim);
      break;
    case css_util::kHasWidthOnly:
      page_dim->set_width(width);
      SetHeightFromAttribute(element, page_dim);
      break;
    case css_util::kNoDimensions:
      SetWidthFromAttribute(element, page_dim);
      SetHeightFromAttribute(element, page_dim);
      break;
  }

  // If the area of image using rendered dimensions is less than the dimensions
  // from the style or image tag attributes, then only resize using rendered
  // dimensions.
  int64 rendered_area = rendered_width * rendered_height;
  int64 image_attribute_area = page_dim->width() * page_dim->height();
  // Note: we check for image_attribute_area = 1 (-1 * -1 = 1) when we have
  // -1(unset) for both height and width from the image attributes.
  if (rendered_area != 0 && ((image_attribute_area != 1 &&
       rendered_area < image_attribute_area) ||
      (image_attribute_area == 1))) {
    page_dim->set_width(rendered_width);
    page_dim->set_height(rendered_height);
    *is_resized_using_rendered_dimensions = true;
    image_resized_using_rendered_dimensions_->Add(1);
  }
}

InlineResult ImageRewriteFilter::TryInline(bool is_html, bool is_critical,
    int64 image_inline_max_bytes, const CachedResult* cached_result,
    ResourceSlot* slot, GoogleString* data_url) {
  int32 image_type_value = cached_result->inlined_image_type();
  if ((image_type_value < IMAGE_UNKNOWN) ||
      (image_type_value > IMAGE_WEBP_LOSSLESS_OR_ALPHA)) {
    // IMAGE_UNKNOWN and IMAGE_WEBP_LOSSLESS_OR_ALPHA must be the smallest
    // and largest values, respectively, in ImageType enum.
    LOG(DFATAL) << "Invalid inlined_image_type in cached_result";
    return INLINE_INTERNAL_ERROR;
  }
  ImageType image_type = static_cast<ImageType>(image_type_value);

  const RequestProperties* request_properties = driver()->request_properties();
  if (!request_properties->SupportsImageInlining() ||
      ((image_type == IMAGE_WEBP ||
        image_type == IMAGE_WEBP_LOSSLESS_OR_ALPHA) &&
       request_properties->ForbidWebpInlining())) {
    return INLINE_UNSUPPORTED_DEVICE;
  }
  if (is_html && driver()->options()->inline_only_critical_images() &&
      !is_critical) {
    return INLINE_NOT_CRITICAL;
  }
  if (!cached_result->has_inlined_data()) {
    return INLINE_NO_DATA;
  }
  StringPiece data = cached_result->inlined_data();
  if (static_cast<int64>(data.size()) >= image_inline_max_bytes) {
    return INLINE_TOO_LARGE;
  }

  // This is the decision point for whether or not an image is suitable for
  // inlining. After this point, we may skip inlining an image, but not
  // because of properties of the image.
  const RewriteOptions* options = driver()->options();
  if (options->cache_small_images_unrewritten()) {
    // Skip rewriting, record the URL for storage in the property cache,
    // suppress future rewrites to this slot, and return immediately.
    GoogleString url(slot->resource()->url());

    // Duplicate URLs are suppressed.
    if (inlinable_urls_.insert(url).second) {
      // This write to the property value allows downstream filters to observe
      // inlinable images within the same flush window. Note that this does not
      // induce a write to the underlying cache -- the value is written only
      // when the filter chain has finished execution.
      StoreUrlInPropertyCache(url);
    }
    // We disable rendering to prevent any rewriting of the URL that we'll
    // advertise in the property cache.
    slot->set_disable_rendering(true);
    return INLINE_CACHE_SMALL_IMAGES_UNREWRITTEN;
  }
  DataUrl(*Image::TypeToContentType(image_type), BASE64, data, data_url);
  return INLINE_SUCCESS;
}

void ImageRewriteFilter::EndElementImpl(HtmlElement* element) {
  // Don't rewrite if the image is broken by a flush.
  if (driver()->HasChildrenInFlushWindow(element)) {
    return;
  }
  // Don't rewrite if there is a pagespeed_no_transform or
  // data-pagespeed-no-transform attribute.
  if (element->FindAttribute(HtmlName::kDataPagespeedNoTransform)) {
    // Remove the attribute
    element->DeleteAttribute(HtmlName::kDataPagespeedNoTransform);
    return;
  }
  if (element->FindAttribute(HtmlName::kPagespeedNoTransform)) {
    // Remove the attribute
    element->DeleteAttribute(HtmlName::kPagespeedNoTransform);
    return;
  }
  // Rewrite any image-valued attributes we find.
  resource_tag_scanner::UrlCategoryVector attributes;
  resource_tag_scanner::ScanElement(element, driver()->options(), &attributes);
  for (int i = 0, n = attributes.size(); i < n; ++i) {
    if (attributes[i].category != semantic_type::kImage ||
        attributes[i].url->DecodedValueOrNull() == NULL) {
      continue;
    }

    // The LSC filter only knows how to handle the src attribute.
    if (attributes[i].url->keyword() == HtmlName::kSrc) {
      // Ask the LSC filter to work out how to handle this element. A return
      // value of true means we don't have to rewrite it so can skip that.
      // The state is carried forward to after we initiate rewriting since
      // we might still have to modify the element.
      LocalStorageCacheFilter::InlineState state;
      if (LocalStorageCacheFilter::AddStorableResource(
              attributes[i].url->DecodedValueOrNull(),
              driver(),
              false /* check cookie */,
              element, &state)) {
        continue;
      }
    }

    BeginRewriteImageUrl(element, attributes[i].url);
  }
}

const UrlSegmentEncoder* ImageRewriteFilter::encoder() const {
  return &encoder_;
}

void ImageRewriteFilter::EncodeUserAgentIntoResourceContext(
    ResourceContext* context) const {
  ImageUrlEncoder::SetWebpAndMobileUserAgent(*driver(), context);
  CssUrlEncoder::SetInliningImages(*driver()->request_properties(), context);
  ImageUrlEncoder::SetSmallScreen(*driver(), context);

  context->set_may_use_save_data_quality(
      driver()->options()->SupportSaveData() &&
      driver()->request_properties()->RequestsSaveData());
}

RewriteContext* ImageRewriteFilter::MakeRewriteContext() {
  ResourceContext* resource_context = new ResourceContext;
  EncodeUserAgentIntoResourceContext(resource_context);
  return new Context(0 /*No CSS inlining, it's html */,
                     this, driver(), NULL /*not nested */,
                     resource_context, false /*not css */,
                     kNotCriticalIndex,
                     false /*not in noscript */,
                     false /*not resized by rendered dimensions*/);
}

RewriteContext* ImageRewriteFilter::MakeNestedRewriteContextForCss(
    int64 css_image_inline_max_bytes, RewriteContext* parent,
    const ResourceSlotPtr& slot) {
  // Copy over the ResourceContext from the parent RewriteContext so that we
  // preserve request specific options, such as whether WebP rewriting is
  // allowed.
  ResourceContext* cloned_context = new ResourceContext;
  const ResourceContext* parent_context = parent->resource_context();
  if (parent_context != NULL) {
    *cloned_context = *parent_context;
  }

  if (cloned_context->libwebp_level() != ResourceContext::LIBWEBP_NONE) {
    // Assignment from parent_context is not sufficient because parent_context
    // checks only UserAgentSupportsWebp when creating the context, but while
    // rewriting the image, rewrite options should also be checked.
    ImageUrlEncoder::SetLibWebpLevel(
        *driver()->options(), *driver()->request_properties(),
        cloned_context);
  }
  Context* context = new Context(css_image_inline_max_bytes,
                                 this, NULL /* driver*/, parent,
                                 cloned_context, true /*is css */,
                                 kNotCriticalIndex,
                                 false /*not in noscript */,
                                 false /*not resized by rendered dimensions*/);
  context->AddSlot(slot);
  return context;
}

RewriteContext* ImageRewriteFilter::MakeNestedRewriteContext(
    RewriteContext* parent, const ResourceSlotPtr& slot) {
  ResourceContext* resource_context = new ResourceContext;
  DCHECK(parent != NULL);
  DCHECK(parent->resource_context() != NULL);
  if (parent != NULL && parent->resource_context() != NULL) {
    *resource_context = *(parent->resource_context());
  }
  Context* context = new Context(
      0 /*No Css inling */, this, NULL /* driver */, parent, resource_context,
      false /*not css */, kNotCriticalIndex, false /*not in noscript */,
      false /*not resized by rendered dimensions*/);
  context->AddSlot(slot);
  return context;
}

bool ImageRewriteFilter::UpdateDesiredImageDimsIfNecessary(
    const ImageDim& image_dim, const ResourceContext& resource_context,
    ImageDim* desired_dim) {
  return false;
}

const RewriteOptions::Filter* ImageRewriteFilter::RelatedFilters(
    int* num_filters) const {
  *num_filters = kRelatedFiltersSize;
  return kRelatedFilters;
}

void ImageRewriteFilter::DisableRelatedFilters(RewriteOptions* options) {
  for (int i = 0; i < kRelatedFiltersSize; ++i) {
    options->DisableFilter(kRelatedFilters[i]);
  }
}

void ImageRewriteFilter::RegisterImageInfo(
    const AssociatedImageInfo& image_info) {
  if (!driver()->options()->Enabled(
          RewriteOptions::kExperimentCollectMobImageInfo)) {
    return;
  }

  image_info_[image_info.url()] = image_info;
}

void ImageRewriteFilter::ReportDroppedRewrite() {
  image_rewrites_dropped_due_to_load_->IncBy(1);
}

bool ImageRewriteFilter::ExtractAssociatedImageInfo(
    const CachedResult* result, RewriteContext* context,
    AssociatedImageInfo* out) {
  bool ret = false;
  if (result->has_image_file_dims()) {
    if (result->url().empty()) {
      if (context->num_slots() == 1) {
        out->set_url(context->slot(0)->resource()->url());
        ret = true;
      }
    } else {
      out->set_url(result->url());
      ret = true;
    }
  }
  if (ret) {
    *out->mutable_dimensions() = result->image_file_dims();
  }
  return ret;
}

}  // namespace net_instaweb
