/*
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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.
 */

#include "glimp/gles/convert_pixel_data.h"

#include "starboard/common/log.h"
#include "starboard/memory.h"

namespace glimp {
namespace gles {

namespace {

// Helper method to properly copy pixel data from a source to destination
// pixel data, taking into account source and destination pitch.
void CopyPixelData(uint8_t* destination,
                   int destination_pitch,
                   const uint8_t* source,
                   int source_pitch,
                   int bytes_per_row,
                   int num_rows) {
  if (destination_pitch == source_pitch) {
    // If the pitches are equal, we can do the entire copy in one memcpy().
    SbMemoryCopy(destination, source, destination_pitch * num_rows);
  } else {
    // If the pitches are not equal, we must memcpy each row separately.
    for (int i = 0; i < num_rows; ++i) {
      SbMemoryCopy(destination + i * destination_pitch,
                   source + i * source_pitch, bytes_per_row);
    }
  }
}

typedef void (*ConvertRowFunction)(int, uint8_t*, const uint8_t*, int);

// Remaps input pixel channels such that 4-byte destination color values will
// have byte X set from source color value's channel_X_source byte.  If
// any value for channel_X_source is set to -1, a 0 is instead set for that
// destination channel.
template <int channel_0_source,
          int channel_1_source,
          int channel_2_source,
          int channel_3_source>
void RemapPixelChannels(int source_bytes_per_pixel,
                        uint8_t* destination,
                        const uint8_t* source,
                        int num_pixels) {
  for (int i = 0; i < num_pixels; ++i) {
    uint8_t channel_0 = channel_0_source == -1 ? 0 : source[channel_0_source];
    uint8_t channel_1 = channel_1_source == -1 ? 0 : source[channel_1_source];
    uint8_t channel_2 = channel_2_source == -1 ? 0 : source[channel_2_source];
    uint8_t channel_3 = channel_3_source == -1 ? 0 : source[channel_3_source];
    destination[0] = channel_0;
    destination[1] = channel_1;
    destination[2] = channel_2;
    destination[3] = channel_3;

    destination += 4;
    source += source_bytes_per_pixel;
  }
}

// Given a destination and source format, returns a function that will convert
// a row of pixels in a source buffer to a row of pixels in a destination
// buffer that contains a different format.  This function may not implement
// every conversion, it is expected that conversion implementations will be
// added as they are needed.
ConvertRowFunction SelectConvertRowFunction(PixelFormat destination_format,
                                            PixelFormat source_format) {
  if (destination_format == source_format) {
    return &RemapPixelChannels<0, 1, 2, 3>;
  } else if (destination_format == kPixelFormatRGBA8 &&
      source_format == kPixelFormatARGB8) {
    return &RemapPixelChannels<1, 2, 3, 0>;
  } else if (destination_format == kPixelFormatRGBA8 &&
             source_format == kPixelFormatBGRA8) {
    return &RemapPixelChannels<2, 1, 0, 3>;
  }

  // Only what is currently needed by dependent libraries is supported, so
  // feel free to add support for more pixel formats here as the need arises.

  return NULL;
}

}  // namespace

void ConvertPixelDataInplace(uint8_t* pixels,
                             int pitch_in_bytes,
                             PixelFormat destination_format,
                             PixelFormat source_format,
                             int width,
                             int height) {
  if (destination_format == source_format) {
    return;
  }
  SB_DCHECK(BytesPerPixel(destination_format) == BytesPerPixel(source_format));
  // The destination format is different from the source format, so we must
  // perform a conversion between pixels.

  // First select the function that will reformat the pixels, based on
  // the destination and source pixel formats.
  ConvertRowFunction convert_row_function =
      SelectConvertRowFunction(destination_format, source_format);
  SB_DCHECK(convert_row_function)
      << "The requested pixel conversion is not yet implemented.";

  // Now, iterate through each row running the selected conversion function on
  // each one.
  uint8_t* pixel_row = pixels;
  for (int row = 0; row < height; ++row) {
    convert_row_function(BytesPerPixel(source_format), pixel_row, pixel_row,
                         width);
    pixel_row += pitch_in_bytes;
  }
}

void ConvertPixelData(uint8_t* destination,
                      int destination_pitch_in_bytes,
                      PixelFormat destination_format,
                      const uint8_t* source,
                      int source_pitch_in_bytes,
                      PixelFormat source_format,
                      int width,
                      int height,
                      bool flip_y) {
  if (destination_format == source_format && !flip_y) {
    CopyPixelData(destination, destination_pitch_in_bytes, source,
                  source_pitch_in_bytes, BytesPerPixel(source_format) * width,
                  height);
  } else {
    // The destination format is different from the source format, so we must
    // perform a conversion between pixels.

    // First select the function that will reformat the pixels, based on
    // the destination and source pixel formats.
    ConvertRowFunction convert_row_function =
        SelectConvertRowFunction(destination_format, source_format);
    SB_DCHECK(convert_row_function)
        << "The requested pixel conversion is not yet implemented.";

    // Now, iterate through each row running the selected conversion function on
    // each one.
    for (int dest_row = 0; dest_row < height; ++dest_row) {
      int source_row = flip_y ? height - dest_row - 1 : dest_row;
      convert_row_function(BytesPerPixel(source_format),
                           destination + dest_row * destination_pitch_in_bytes,
                           source + source_row * source_pitch_in_bytes, width);
    }
  }
}

}  // namespace gles
}  // namespace glimp
