// Copyright 2025 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

package lowleveljpeg_test

import (
	"bytes"
	"fmt"
	"image/jpeg"
	"image/png"
	"log"
	"os"

	"github.com/google/wuffs/lib/lowleveljpeg"
)

// Example_yCbCr444 demonstrates loading an RGB PNG, converting to YCbCr and to
// DCT space and saving as a 4:4:4 JPEG. Multiple JPEG outputs from the one PNG
// input demonstrate making further transforms during conversion.
func Example_yCbCr444() {
	// levels holds a rough, ad hoc measure of a coefficient's frequency, in
	// DCT space. Low (or high) levels[i] mean low (or high) frequency.
	//
	// levels[0] == 0 is the DC coefficient. The others are AC coefficients.
	levels := [64]uint8{
		0, 1, 2, 3, 4, 5, 6, 7,
		1, 1, 2, 3, 4, 5, 6, 7,
		2, 2, 2, 3, 4, 5, 6, 7,
		3, 3, 3, 3, 4, 5, 6, 7,
		4, 4, 4, 4, 4, 5, 6, 7,
		5, 5, 5, 5, 5, 5, 6, 7,
		6, 6, 6, 6, 6, 6, 6, 7,
		7, 7, 7, 7, 7, 7, 7, 7,
	}

	// Load the source PNG. We will make numerous JPEG encodings of transformed
	// versions of this PNG image.
	f, err := os.Open("../../test/data/hippopotamus.regular.png")
	if err != nil {
		log.Fatalf("os.Open: %v", err)
	}
	defer f.Close()
	src, err := png.Decode(f)
	if err != nil {
		log.Fatalf("png.Decode: %v", err)
	}

	// Each example (each output JPEG) has a name fragment and a transform from
	// source BlockU8 values to destination BlockI16 values.
	examples := []struct {
		nameFragment string
		quality      int
		transform    func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8)
	}{{

		// Apply the ForwardDCT with no further changes. The resultant JPEG is
		// a low quality (but small in file size) version of the source PNG.
		nameFragment: "0_quality25",
		quality:      25,
		transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
			dst[0].ForwardDCTFrom(&src[0])
			dst[1].ForwardDCTFrom(&src[1])
			dst[2].ForwardDCTFrom(&src[2])
		},
	}, {

		// Ditto, with default quality.
		nameFragment: "1_quality75",
		quality:      75,
		transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
			dst[0].ForwardDCTFrom(&src[0])
			dst[1].ForwardDCTFrom(&src[1])
			dst[2].ForwardDCTFrom(&src[2])
		},
	}, {

		// Ditto, with high quality.
		nameFragment: "2_quality100",
		quality:      100,
		transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
			dst[0].ForwardDCTFrom(&src[0])
			dst[1].ForwardDCTFrom(&src[1])
			dst[2].ForwardDCTFrom(&src[2])
		},
	}, {

		// Like 2_quality100 but swap the Chroma-blue and Chroma-red channels.
		nameFragment: "3_swap_cb_cr",
		quality:      100,
		transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
			dst[0].ForwardDCTFrom(&src[0])
			dst[1].ForwardDCTFrom(&src[2]) // Note the "1" and "2".
			dst[2].ForwardDCTFrom(&src[1]) // Note the "2" and "1".
		},
	}, {

		// Set the 8×8 blocks of the Luma channel to neutral (0x80) except for
		// each top-left corner, which is black (0x00). Chromas are unchanged.
		nameFragment: "4_chroma_only",
		quality:      100,
		transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
			s0 := lowleveljpeg.BlockU8{}
			s0[0] = 0x00
			for i := 1; i < 64; i++ {
				s0[i] = lowleveljpeg.BlockU8NeutralValue
			}
			dst[0].ForwardDCTFrom(&s0)
			dst[1].ForwardDCTFrom(&src[1])
			dst[2].ForwardDCTFrom(&src[2])
		},
	}, {

		// Set the Chroma channels to neutral, as well as any Luma coefficients
		// that have any horizontal variation (within an 8×8 block). What
		// remains are the DC and vertical-only Luma coefficients.
		nameFragment: "5_vertical_luma",
		quality:      100,
		transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
			dst[0].ForwardDCTFrom(&src[0])
			for i := 0; i < 64; i++ {
				if (i & 7) != 0 {
					dst[0][i] = lowleveljpeg.BlockI16NeutralValue
				}
			}
			dst[1] = lowleveljpeg.BlockI16{}
			dst[2] = lowleveljpeg.BlockI16{}
		},
	}, {

		// Set the Chroma channels to neutral, as well as any medium- or
		// high-frequency Luma coefficients.
		nameFragment: "6_low_frequency_luma",
		quality:      100,
		transform: func(dst *lowleveljpeg.Array3BlockI16, src *lowleveljpeg.Array3BlockU8) {
			dst[0] = src[0].ForwardDCT()
			for i := 0; i < 64; i++ {
				if levels[i] > 2 {
					dst[0][i] = 0
				}
			}
			dst[1] = lowleveljpeg.BlockI16{}
			dst[2] = lowleveljpeg.BlockI16{}
		},
	}}

	// Process each example.
	for _, example := range examples {
		// Initialize the encoder.
		quants := lowleveljpeg.Array2QuantizationFactors{}
		quants.SetToStandardValues(example.quality)
		opts := &lowleveljpeg.EncoderOptions{
			QuantizationFactors: &quants,
		}
		bounds := src.Bounds()
		buf := &bytes.Buffer{}
		enc := lowleveljpeg.Encoder{}
		if err := enc.Reset(buf, lowleveljpeg.ColorTypeYCbCr444, bounds.Dx(), bounds.Dy(), opts); err != nil {
			log.Fatalf("enc.Reset: %v", err)
		}

		// Extract, transform and add each MCU (Mininum Coded Unit). For 4:4:4
		// Chroma subsampling, each MCU is 8×8 and contains 3 blocks: 1 Y, 1
		// Cb, 1 Cr.
		srcU8s := lowleveljpeg.Array3BlockU8{}
		srcI16s := lowleveljpeg.Array3BlockI16{}
		for y := bounds.Min.Y; y < bounds.Max.Y; y += 8 {
			for x := bounds.Min.X; x < bounds.Max.X; x += 8 {
				srcU8s.ExtractYCbCrFrom(src, x, y)
				example.transform(&srcI16s, &srcU8s)
				if err := enc.Add3(buf, &srcI16s); err != nil {
					log.Fatalf("enc.Add3: %v", err)
				}
			}
		}

		// As a basic consistency check, confirm that the resultant bytes are a
		// valid JPEG. When copy/pasting this code, you can omit this step.
		dstBytes := buf.Bytes()
		if _, err := jpeg.Decode(bytes.NewReader(dstBytes)); err != nil {
			log.Fatalf("jpeg.Decode: %v", err)
		}

		// Change writeTmpFiles to true if you want to visually inspect the output.
		const writeTmpFiles = false
		dstFilename := fmt.Sprintf("/tmp/lowleveljpeg_example_%s.jpeg", example.nameFragment)
		if writeTmpFiles {
			if err := os.WriteFile(dstFilename, dstBytes, 0644); err != nil {
				log.Fatalf("os.WriteFile: %v", err)
			}
			fmt.Println("Wrote  ", dstFilename)
		} else {
			fmt.Println("Skipped", dstFilename)
		}
	}

	// Output:
	// Skipped /tmp/lowleveljpeg_example_0_quality25.jpeg
	// Skipped /tmp/lowleveljpeg_example_1_quality75.jpeg
	// Skipped /tmp/lowleveljpeg_example_2_quality100.jpeg
	// Skipped /tmp/lowleveljpeg_example_3_swap_cb_cr.jpeg
	// Skipped /tmp/lowleveljpeg_example_4_chroma_only.jpeg
	// Skipped /tmp/lowleveljpeg_example_5_vertical_luma.jpeg
	// Skipped /tmp/lowleveljpeg_example_6_low_frequency_luma.jpeg
}
