<commit_before>module Tootsie
  module Processors

    class ImageProcessor

      def initialize(params = {})
        @input_url = params[:input_url]
        @versions = [params[:versions] || {}].flatten
        @logger = Application.get.logger
        @extractor = ImageMetadataExtractor.new(:logger => @logger)
      end

      def valid?
        return @input_url && !@versions.blank?
      end

      def params
        return {
          :input_url => @input_url,
          :versions => @versions
        }
      end

      def execute!(&block)
        result = {:outputs => []}
        input, output = Input.new(@input_url), nil
        begin
          input.get!
          begin
            versions.each_with_index do |version_options, version_index|
              version_options = version_options.with_indifferent_access
              @logger.info("Handling version: #{version_options.inspect}")

              output = Output.new(version_options[:target_url])
              begin
                result[:metadata] ||= @extractor.extract_from_file(input.file_name)

                original_depth = nil
                original_width = nil
                original_height = nil
                original_type = nil
                original_format = nil
                original_orientation = nil
                CommandRunner.new("identify -format '%z %w %h %m %[EXIF:Orientation] %r' :file").
                  run(:file => input.file_name) do |line|
                  if line =~ /(\d+) (\d+) (\d+) ([^\s]+) (\d+)? (.+)/
                    original_depth, original_width, original_height = $~[1, 3].map(&:to_i)
                    original_format = $4.downcase
                    original_orientation = $5.try(:to_i)
                    original_type = $6
                  end
                end
                unless original_width and original_height
                  raise "Unable to determine dimensions of input image"
                end

                if (output_format = version_options[:format])
                  # Sanitize format so we can use it in file name
                  output_format = output_format.to_s
                  output_format.gsub!(/[^\w]/, '')
                end
                output_format ||= original_format
                result[:format] = output_format

                # Correct for EXIF orientation
                if [5, 6, 7, 8].include?(original_orientation)
                  original_width, original_height = original_height, original_width
                end

                original_aspect = original_height / original_width.to_f

                result[:width] = original_width
                result[:height] = original_height
                result[:depth] = original_depth

                medium = version_options[:medium]
                medium &&= medium.to_sym

                new_width, new_height =
                  version_options[:width].try(:to_i),
                  version_options[:height].try(:to_i)
                if new_width
                  new_height ||= (new_width * original_aspect).ceil
                elsif new_height
                  new_width ||= (new_height / original_aspect).ceil
                else
                  new_width, new_height = original_width, original_height
                end

                scale_width, scale_height = new_width, new_height
                scale = (version_options[:scale] || 'down').to_sym
                case scale
                  when :up, :none
                    # Do nothing
                  when :down
                    if scale_width > original_width
                      scale_width = original_width
                      scale_height = (scale_width * original_aspect).ceil
                    elsif scale_height > original_height
                      scale_height = original_height
                      scale_width = (scale_height / original_aspect).ceil
                    end
                  when :fit
                    if (scale_width * original_aspect).ceil < new_height
                      scale_height = new_height
                      scale_width = (new_height / original_aspect).ceil
                    elsif (scale_height / original_aspect).ceil < new_width
                      scale_width = new_width
                      scale_height = (scale_width * original_aspect).ceil
                    end
                end

                convert_command = "convert"
                convert_options = {
                  :input_file => input.file_name,
                  :output_file => "'#{output_format}:#{output.file_name}'"
                }

                if original_format != version_options[:format] and %(gif tiff).include?(original_format)
                  # Remove additional frames (animation, TIFF thumbnails) not
                  # supported by the output format
                  convert_command << ' -delete "1-999" -flatten -scene 1'
                end

                if scale != :none
                  convert_command << " -resize :resize"<commit_msg>Clean up scaled dimensions calculation.<commit_after>module Tootsie
  module Processors

    class ImageProcessor

      def initialize(params = {})
        @input_url = params[:input_url]
        @versions = [params[:versions] || {}].flatten
        @logger = Application.get.logger
        @extractor = ImageMetadataExtractor.new(:logger => @logger)
      end

      def valid?
        return @input_url && !@versions.blank?
      end

      def params
        return {
          :input_url => @input_url,
          :versions => @versions
        }
      end

      def execute!(&block)
        result = {:outputs => []}
        input, output = Input.new(@input_url), nil
        begin
          input.get!
          begin
            versions.each_with_index do |version_options, version_index|
              version_options = version_options.with_indifferent_access
              @logger.info("Handling version: #{version_options.inspect}")

              output = Output.new(version_options[:target_url])
              begin
                result[:metadata] ||= @extractor.extract_from_file(input.file_name)

                original_depth = nil
                original_width = nil
                original_height = nil
                original_type = nil
                original_format = nil
                original_orientation = nil
                CommandRunner.new("identify -format '%z %w %h %m %[EXIF:Orientation] %r' :file").
                  run(:file => input.file_name) do |line|
                  if line =~ /(\d+) (\d+) (\d+) ([^\s]+) (\d+)? (.+)/
                    original_depth, original_width, original_height = $~[1, 3].map(&:to_i)
                    original_format = $4.downcase
                    original_orientation = $5.try(:to_i)
                    original_type = $6
                  end
                end
                unless original_width and original_height
                  raise "Unable to determine dimensions of input image"
                end

                if (output_format = version_options[:format])
                  # Sanitize format so we can use it in file name
                  output_format = output_format.to_s
                  output_format.gsub!(/[^\w]/, '')
                end
                output_format ||= original_format
                result[:format] = output_format

                # Correct for EXIF orientation
                if [5, 6, 7, 8].include?(original_orientation)
                  original_width, original_height = original_height, original_width
                end

                original_aspect = original_height / original_width.to_f

                result[:width] = original_width
                result[:height] = original_height
                result[:depth] = original_depth

                medium = version_options[:medium]
                medium &&= medium.to_sym

                new_width, new_height =
                  version_options[:width].try(:to_i),
                  version_options[:height].try(:to_i)
                if new_width
                  new_height ||= (new_width * original_aspect).ceil
                elsif new_height
                  new_width ||= (new_height / original_aspect).ceil
                else
                  new_width, new_height = original_width, original_height
                end

                scale = (version_options[:scale] || 'down').to_sym
                case scale
                  when :down
                    if new_width > original_width
                      scale_width = original_width
                      scale_height = (original_width * original_aspect).ceil
                    elsif new_height > original_height
                      scale_height = original_height
                      scale_width = (original_height / original_aspect).ceil
                    end
                  when :fit
                    if (new_width * original_aspect).ceil < new_height
                      scale_height = new_height
                      scale_width = (new_height / original_aspect).ceil
                    elsif (new_height / original_aspect).ceil < new_width
                      scale_width = new_width
                      scale_height = (new_width * original_aspect).ceil
                    end
                end
                scale_width ||= new_width
                scale_height ||= new_height

                convert_command = "convert"
                convert_options = {
                  :input_file => input.file_name,
                  :output_file => "'#{output_format}:#{output.file_name}'"
                }

                if original_format != version_options[:format] and %(gif tiff).include?(original_format)
                  # Remove additional frames (animation, TIFF thumbnails) not
                  # supported by the output format
                  convert_command << ' -delete "1-999" -flatten -scene 1'
                end

                if scale != :none
                  convert_command << " -resize :resize"
{'fraction_non_alphanumeric': 0.08342415535519668, 'fraction_numerical': 0.0027741999405528584, 'mean_word_length': 1.4200431551186765, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '514820', 'n_tokens_mistral': 2587, 'n_tokens_neox': 2366, 'n_words': 552}