// Copyright 2022 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// SPDX-License-Identifier: Apache-2.0 OR MIT

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

/*
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__JPEG
#define WUFFS_CONFIG__MODULE__NETPBM
#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;
}
