LCOV - code coverage report
Current view: top level - src - webp.c (source / functions) Coverage Total Hit
Test: colopresso Coverage Report Lines: 81.7 % 71 58
Test Date: 2025-12-13 15:41:21 Functions: 100.0 % 4 4
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-or-later
       3              :  *
       4              :  * This file is part of colopresso
       5              :  *
       6              :  * Copyright (C) 2025 COLOPL, Inc.
       7              :  *
       8              :  * Author: Go Kudo <g-kudo@colopl.co.jp>
       9              :  * Developed with AI (LLM) code assistance. See `NOTICE` for details.
      10              :  */
      11              : 
      12              : #include <errno.h>
      13              : #include <stdbool.h>
      14              : #include <stdint.h>
      15              : #include <stdio.h>
      16              : #include <stdlib.h>
      17              : #include <string.h>
      18              : 
      19              : #include <webp/encode.h>
      20              : 
      21              : #include <colopresso.h>
      22              : 
      23              : #include "internal/log.h"
      24              : #include "internal/webp.h"
      25              : 
      26              : static int g_last_webp_error = 0;
      27              : 
      28            1 : int cpres_webp_get_last_error(void) { return g_last_webp_error; }
      29              : 
      30           28 : void cpres_webp_set_last_error(int error_code) { g_last_webp_error = error_code; }
      31              : 
      32           27 : static void apply_webp_config(WebPConfig *webp_config, const cpres_config_t *config) {
      33           27 :   webp_config->quality = config->webp_quality;
      34           27 :   webp_config->target_size = config->webp_target_size;
      35           27 :   webp_config->target_PSNR = config->webp_target_psnr;
      36           27 :   webp_config->method = config->webp_method;
      37           27 :   webp_config->segments = config->webp_segments;
      38           27 :   webp_config->sns_strength = config->webp_sns_strength;
      39           27 :   webp_config->filter_strength = config->webp_filter_strength;
      40           27 :   webp_config->filter_sharpness = config->webp_filter_sharpness;
      41           27 :   webp_config->filter_type = config->webp_filter_type;
      42           27 :   webp_config->autofilter = config->webp_autofilter;
      43           27 :   webp_config->alpha_compression = config->webp_alpha_compression;
      44           27 :   webp_config->alpha_filtering = config->webp_alpha_filtering;
      45           27 :   webp_config->alpha_quality = config->webp_alpha_quality;
      46           27 :   webp_config->pass = config->webp_pass;
      47           27 :   webp_config->preprocessing = config->webp_preprocessing;
      48           27 :   webp_config->partitions = config->webp_partitions;
      49           27 :   webp_config->partition_limit = config->webp_partition_limit;
      50           27 :   webp_config->emulate_jpeg_size = config->webp_emulate_jpeg_size;
      51           27 :   webp_config->thread_level = (config->webp_thread_level > 0) ? 1 : 0;
      52           27 :   webp_config->low_memory = config->webp_low_memory;
      53           27 :   webp_config->near_lossless = config->webp_near_lossless;
      54           27 :   webp_config->exact = config->webp_exact;
      55           27 :   webp_config->use_delta_palette = config->webp_use_delta_palette;
      56           27 :   webp_config->use_sharp_yuv = config->webp_use_sharp_yuv;
      57           27 :   webp_config->lossless = config->webp_lossless;
      58           27 : }
      59              : 
      60           28 : cpres_error_t cpres_webp_encode_rgba_to_memory(uint8_t *rgba_data, uint32_t width, uint32_t height, uint8_t **webp_data, size_t *webp_size, const cpres_config_t *config) {
      61              :   WebPConfig webp_config;
      62              :   WebPPicture picture;
      63              :   WebPMemoryWriter writer;
      64              : 
      65           28 :   if (!rgba_data || !webp_data || !webp_size || !config) {
      66            0 :     return CPRES_ERROR_INVALID_PARAMETER;
      67              :   }
      68              : 
      69           28 :   memset(&webp_config, 0, sizeof(webp_config));
      70           28 :   memset(&picture, 0, sizeof(picture));
      71           28 :   memset(&writer, 0, sizeof(writer));
      72              : 
      73           28 :   cpres_log(CPRES_LOG_LEVEL_DEBUG, "Starting WebP encoding to memory - %dx%d pixels", width, height);
      74              : 
      75           28 :   if (!WebPConfigPreset(&webp_config, WEBP_PRESET_DEFAULT, config->webp_quality)) {
      76            1 :     return CPRES_ERROR_INVALID_PARAMETER;
      77              :   }
      78              : 
      79           27 :   apply_webp_config(&webp_config, config);
      80              : 
      81           27 :   if (!WebPValidateConfig(&webp_config)) {
      82            0 :     return CPRES_ERROR_INVALID_PARAMETER;
      83              :   }
      84              : 
      85           27 :   if (!WebPPictureInit(&picture)) {
      86            0 :     return CPRES_ERROR_OUT_OF_MEMORY;
      87              :   }
      88              : 
      89           27 :   picture.width = (int)width;
      90           27 :   picture.height = (int)height;
      91           27 :   picture.use_argb = 1;
      92              : 
      93           27 :   if (!WebPPictureImportRGBA(&picture, rgba_data, width * 4)) {
      94            0 :     WebPPictureFree(&picture);
      95            0 :     return CPRES_ERROR_ENCODE_FAILED;
      96              :   }
      97              : 
      98           27 :   WebPMemoryWriterInit(&writer);
      99           27 :   picture.writer = WebPMemoryWrite;
     100           27 :   picture.custom_ptr = &writer;
     101              : 
     102           27 :   cpres_log(CPRES_LOG_LEVEL_DEBUG, "Starting WebP encoding (memory)...");
     103              : 
     104           27 :   if (!WebPEncode(&webp_config, &picture)) {
     105            0 :     cpres_webp_set_last_error(picture.error_code);
     106            0 :     cpres_log(CPRES_LOG_LEVEL_ERROR, "WebP encoding failed - error code: %d", picture.error_code);
     107            0 :     WebPMemoryWriterClear(&writer);
     108            0 :     WebPPictureFree(&picture);
     109            0 :     return CPRES_ERROR_ENCODE_FAILED;
     110              :   }
     111           27 :   cpres_webp_set_last_error(0);
     112              : 
     113           27 :   cpres_log(CPRES_LOG_LEVEL_DEBUG, "WebP encoding successful - size: %zu bytes", writer.size);
     114              : 
     115           27 :   *webp_data = (uint8_t *)malloc(writer.size);
     116           27 :   if (!*webp_data) {
     117            0 :     WebPMemoryWriterClear(&writer);
     118            0 :     WebPPictureFree(&picture);
     119            0 :     return CPRES_ERROR_OUT_OF_MEMORY;
     120              :   }
     121              : 
     122           27 :   memcpy(*webp_data, writer.mem, writer.size);
     123           27 :   *webp_size = writer.size;
     124              : 
     125           27 :   WebPMemoryWriterClear(&writer);
     126           27 :   WebPPictureFree(&picture);
     127              : 
     128           27 :   return CPRES_OK;
     129              : }
        

Generated by: LCOV version 2.0-1