// Copyright 2022 The Wuffs Authors.
//
// 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
//
//    https://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.

// ----------------

/*
print-average-pixel prints the average color of an image's pixels (as well as
the image file format, width and height). It's a toy program to demonstrate how
to use the wuffs_aux C++ API to decode an image and iterate over its pixels.
*/

#include <inttypes.h>
#include <stdio.h>

// Wuffs ships as a "single file C library" or "header file library" as per
// https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
//
// To use that single file as a "foo.c"-like implementation, instead of a
// "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or
// compiling it.
#define WUFFS_IMPLEMENTATION

// Defining the WUFFS_CONFIG__STATIC_FUNCTIONS macro is optional, but when
// combined with WUFFS_IMPLEMENTATION, it demonstrates making all of Wuffs'
// functions have static storage.
//
// This can help the compiler ignore or discard unused code, which can produce
// faster compiles and smaller binaries. Other motivations are discussed in the
// "ALLOW STATIC IMPLEMENTATION" section of
// https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
#define WUFFS_CONFIG__STATIC_FUNCTIONS

// Defining the WUFFS_CONFIG__MODULE* macros are optional, but it lets users of
// release/c/etc.c choose which parts of Wuffs to build. That file contains the
// entire Wuffs standard library, implementing a variety of codecs and file
// formats. Without this macro definition, an optimizing compiler or linker may
// very well discard Wuffs code for unused codecs, but listing the Wuffs
// modules we use makes that process explicit. Preprocessing means that such
// code simply isn't compiled.
#define WUFFS_CONFIG__MODULES
#define WUFFS_CONFIG__MODULE__ADLER32
#define WUFFS_CONFIG__MODULE__AUX__BASE
#define WUFFS_CONFIG__MODULE__AUX__IMAGE
#define WUFFS_CONFIG__MODULE__BASE
#define WUFFS_CONFIG__MODULE__BMP
#define WUFFS_CONFIG__MODULE__CRC32
#define WUFFS_CONFIG__MODULE__DEFLATE
#define WUFFS_CONFIG__MODULE__GIF
#define WUFFS_CONFIG__MODULE__LZW
#define WUFFS_CONFIG__MODULE__NIE
#define WUFFS_CONFIG__MODULE__PNG
#define WUFFS_CONFIG__MODULE__TGA
#define WUFFS_CONFIG__MODULE__WBMP
#define WUFFS_CONFIG__MODULE__ZLIB

// If building this program in an environment that doesn't easily accommodate
// relative includes, you can use the script/inline-c-relative-includes.go
// program to generate a stand-alone C file.
#include "../release/c/wuffs-unsupported-snapshot.c"

class MyCallbacks : public wuffs_aux::DecodeImageCallbacks {
 public:
  MyCallbacks() : m_fourcc(0) {}

  uint32_t m_fourcc;

 private:
  wuffs_base__image_decoder::unique_ptr  //
  SelectDecoder(uint32_t fourcc,
                wuffs_base__slice_u8 prefix_data,
                bool prefix_closed) override {
    // Save the fourcc value (you can think of it as like a 'MIME type' but in
    // uint32_t form) before calling the superclass' implementation.
    //
    // The "if (m_fourcc == 0)" is because SelectDecoder can be called multiple
    // times. Files that are nominally BMP images can contain complete JPEG or
    // PNG images. This program prints the outer file format, the first one
    // encountered, not the inner one.
    if (m_fourcc == 0) {
      m_fourcc = fourcc;
    }
    return wuffs_aux::DecodeImageCallbacks::SelectDecoder(fourcc, prefix_data,
                                                          prefix_closed);
  }

  wuffs_base__pixel_format  //
  SelectPixfmt(const wuffs_base__image_config& image_config) override {
    // This is the same as the superclass' implementation, but makes it
    // explicit that this program uses a single-plane pixel buffer (as opposed
    // to e.g. 3-plane YCbCr) with 4 bytes per pixel (in B, G, R, A order) and
    // premultiplied alpha.
    return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);
  }

  AllocPixbufResult  //
  AllocPixbuf(const wuffs_base__image_config& image_config,
              bool allow_uninitialized_memory) override {
    // This just calls the superclass' implementation, but if you wanted more
    // control about how the pixel buffer's memory is allocated and freed,
    // change the code here. For example, if you (the wuffs_aux::DecodeImage
    // caller) want to use an already-allocated buffer, instead of Wuffs (the
    // callee) allocating a new buffer.
    //
    // The example/sdl-imageviewer/sdl-imageviewer.cc file demonstrates
    // overriding the AllocPixbuf method with the "bring your own buffer"
    // approach. In the sdl-imageviewer case, the pixel buffer is allocated by
    // SDL and lent to Wuffs, instead of allocated by Wuffs.
    return wuffs_aux::DecodeImageCallbacks::AllocPixbuf(
        image_config, allow_uninitialized_memory);
  }
};

void  //
handle(const char* filename, FILE* f) {
  MyCallbacks callbacks;
  wuffs_aux::sync_io::FileInput input(f);
  wuffs_aux::DecodeImageResult res = wuffs_aux::DecodeImage(callbacks, input);
  if (!res.error_message.empty()) {
    printf("%-30s %s\n", filename, res.error_message.c_str());
    return;
  } else if (res.pixbuf.pixcfg.pixel_format().repr !=
             WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) {
    printf("%-30s internal error: inconsistent pixel format\n", filename);
    return;
  }

  wuffs_base__table_u8 table = res.pixbuf.plane(0);
  uint32_t w = res.pixbuf.pixcfg.width();
  uint32_t h = res.pixbuf.pixcfg.height();

  uint64_t count = 0;
  uint64_t color_b = 0;
  uint64_t color_g = 0;
  uint64_t color_r = 0;
  uint64_t color_a = 0;
  for (uint32_t y = 0; y < h; y++) {
    const uint8_t* ptr = table.ptr + (y * table.stride);
    for (uint32_t x = 0; x < w; x++) {
      count++;
      color_b += *ptr++;
      color_g += *ptr++;
      color_r += *ptr++;
      color_a += *ptr++;
    }
  }
  if (count > 0) {
    color_b = (color_b + (count / 2)) / count;
    color_g = (color_g + (count / 2)) / count;
    color_r = (color_r + (count / 2)) / count;
    color_a = (color_a + (count / 2)) / count;
  }

  printf("%-30s %c%c%c%c   %5" PRIu32 " x %5" PRIu32
         "   AverageARGB: %02X%02X%02X%02X\n",  //
         filename,                              //
         (0xFF & (callbacks.m_fourcc >> 24)),   //
         (0xFF & (callbacks.m_fourcc >> 16)),   //
         (0xFF & (callbacks.m_fourcc >> 8)),    //
         (0xFF & (callbacks.m_fourcc >> 0)),    //
         w, h,                                  //
         (int)(color_a),                        //
         (int)(color_r),                        //
         (int)(color_g),                        //
         (int)(color_b));

  // While it's valid to deference table.ptr in this function, the end of scope
  // here means that the res.pixbuf_mem_owner destructor will free the backing
  // memory (unless you modified the AllocPixbuf method above).
  //
  // If you wanted to return the pixel buffer to the caller, either return the
  // wuffs_aux::MemOwner (a type alias for "std::unique_ptr<void,
  // decltype(&free)>") too, or call res.pixbuf_mem_owner.release() before
  // returning and manually free the backing memory at an appropriate time.
}

int  //
main(int argc, char** argv) {
  for (int i = 1; i < argc; i++) {
    FILE* f = fopen(argv[i], "r");
    if (!f) {
      printf("%-30s could not open file: %s\n", argv[i], strerror(errno));
      continue;
    }
    handle(argv[i], f);
    fclose(f);
  }
  return 0;
}
