#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "stb_image.h"   // stb_image 头文件，用于解码 PNG/JPG
#include "stb_image_resize.h"
#include "webp/encode.h" // WebP 头文件，用于编码 WebP


extern "C" {

    // 将输入的 JPG/PNG 数据转换为 WebP，并返回 WebP 数据
    unsigned char *convert_image_to_webp(const uint8_t *input_data, size_t input_size,int input_width,int input_height, int target_width, int target_height, float quality_factor, size_t *output_size, int preserve_alpha = 0,int is_original = 0) {
        int width, height, channels;

        unsigned char *decoded_data = nullptr;
        if (!is_original) {
            decoded_data = stbi_load_from_memory(input_data, input_size, &width, &height, &channels, 0); // 0自动判断是否保留 alpha 通道加载
        } else {
            decoded_data = (unsigned char *)input_data;
            // 当使用原始数据时，需要确保width和height已设置
            width = input_width;
            height = input_height;
            channels = preserve_alpha ? 4 : 3;
        }
        // 使用 stb_image 解码输入图像（根据 preserve_alpha 决定加载通道数）

        if (!decoded_data) {
            // printf("stbi_failure_reason: %s\n", stbi_failure_reason());
            return nullptr; // 图像解码失败
        }

        // 如果需要调整尺寸，则进行调整
        unsigned char *resized_data = decoded_data;
        if (target_width > 0 && target_height > 0) {
            // 分配用于存储调整大小后图像的缓冲区
            resized_data = (unsigned char *)malloc(target_width * target_height * channels); // 根据是否保留 alpha 通道调整缓冲区大小

            if (!resized_data) {
                // 内存分配失败的处理
                fprintf(stderr, "Failed to allocate memory for resized image.\n");
                stbi_image_free(decoded_data); // 释放原始解码数据
                return NULL;
            }

            // 使用 stb_image_resize 调整图像大小
            int result = stbir_resize_uint8(decoded_data, width, height, 0,
                                            resized_data, target_width, target_height, 0, channels);

            if (!result) {
                // 如果调整大小失败，释放已分配的内存
                fprintf(stderr, "Image resizing failed.\n");
                free(resized_data);
                stbi_image_free(decoded_data);
                return NULL;
            }
        } else {
            target_width = width;
            target_height = height;
        }

        // 使用 libwebp 的有损编码函数（WebPEncodeRGB）将 RGB 图像编码为 WebP
        unsigned char *webp_output = NULL;
        if (channels == 4) {
            *output_size = WebPEncodeRGBA(resized_data, target_width, target_height, target_width * 4, quality_factor, &webp_output);
        } else if (channels == 3) {
            *output_size = WebPEncodeRGB(resized_data, target_width, target_height, target_width * 3, quality_factor, &webp_output);
        }

        // 释放解码后的图像内存
        stbi_image_free(decoded_data);
        if (resized_data != decoded_data) {
            free(resized_data); // 如果调整了大小，则释放调整大小后的数据
        }

        return webp_output; // 返回 WebP 编码后的数据
    }
}