Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
imageio_webp.c
Go to the documentation of this file.
1/*
2 This file is part of the Ansel project.
3 Copyright (C) 2023 Alynx Zhou.
4
5 Ansel is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 Ansel is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Ansel. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include "common/darktable.h"
20#include <inttypes.h>
21
22#include <webp/decode.h>
23#include <webp/mux.h>
24
25#include "common/image.h"
26#include "common/imageio.h"
27#include "develop/imageop.h" // for IOP_CS_RGB
28
30{
31 int w, h;
32 WebPMux *mux;
33 WebPData wp_data;
34 WebPData icc_profile;
35
36 FILE *f = g_fopen(filename, "rb");
37 if(IS_NULL_PTR(f))
38 {
39 dt_print(DT_DEBUG_IMAGEIO, "[webp_open] cannot open file for read: %s\n", filename);
41 }
42
43 fseek(f, 0, SEEK_END);
44 size_t filesize = ftell(f);
45 fseek(f, 0, SEEK_SET);
46
47 void *read_buffer = g_malloc(filesize);
48
49 if(fread(read_buffer, 1, filesize, f) != filesize)
50 {
51 fclose(f);
52 dt_free(read_buffer);
53 dt_print(DT_DEBUG_IMAGEIO, "[webp_open] failed to read %" G_GSIZE_FORMAT " bytes from %s\n", filesize, filename);
55 }
56 fclose(f);
57
58 // WebPGetInfo should tell us the image dimensions needed for darktable image buffer allocation
59 if(!WebPGetInfo(read_buffer, filesize, &w, &h))
60 {
61 // If we couldn't get the webp metadata, then the file we're trying to read is most likely in
62 // a different format (darktable just trying different loaders until it finds the right one).
63 // We just have to return without complaining.
64 dt_free(read_buffer);
66 }
67 img->width = w;
68 img->height = h;
69 img->dsc.channels = 4;
70 img->dsc.datatype = TYPE_FLOAT;
71 img->dsc.bpp = 4 * sizeof(float);
72 img->dsc.cst = IOP_CS_RGB;
73 img->dsc.filters = 0u;
74 img->flags &= ~DT_IMAGE_RAW;
75 img->flags &= ~DT_IMAGE_S_RAW;
76 img->flags &= ~DT_IMAGE_HDR;
77 img->flags |= DT_IMAGE_LDR;
78 img->loader = LOADER_WEBP;
79
80 if(IS_NULL_PTR(mbuf))
81 {
82 dt_free(read_buffer);
83 return DT_IMAGEIO_OK;
84 }
85
86 float *mipbuf = (float *)dt_mipmap_cache_alloc(mbuf, img);
87 if(IS_NULL_PTR(mipbuf))
88 {
89 dt_free(read_buffer);
90 dt_print(DT_DEBUG_IMAGEIO, "[webp_open] could not alloc full buffer for image: %s\n", img->filename);
92 }
93
94 uint8_t *int_RGBA_buf = WebPDecodeRGBA(read_buffer, filesize, &w, &h);
95 if(IS_NULL_PTR(int_RGBA_buf))
96 {
97 dt_free(read_buffer);
98 dt_print(DT_DEBUG_IMAGEIO,"[webp_open] failed to decode file: %s\n", filename);
100 }
101
102 uint8_t intval;
103 float floatval;
104 __OMP_PARALLEL_FOR__(private(intval, floatval))
105 for(int i=0; i < w*h*4; i++)
106 {
107 intval = *(int_RGBA_buf+i);
108 floatval = intval / 255.f;
109 *(mipbuf+i) = floatval;
110 }
111
112 WebPFree(int_RGBA_buf);
113
114 wp_data.bytes = (uint8_t *)read_buffer;
115 wp_data.size = filesize;
116 mux = WebPMuxCreate(&wp_data, 0); // 0 = data will NOT be copied to the mux object
117
118 if(mux)
119 {
120 WebPMuxGetChunk(mux, "ICCP", &icc_profile);
121 if(icc_profile.size)
122 {
123 img->profile_size = icc_profile.size;
124 img->profile = (uint8_t *)g_malloc0(icc_profile.size);
125 memcpy(img->profile, icc_profile.bytes, icc_profile.size);
126 }
127 WebPMuxDelete(mux);
128 }
129
130 dt_free(read_buffer);
131 return DT_IMAGEIO_OK;
132}
133
134// clang-format off
135// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
136// vim: shiftwidth=2 expandtab tabstop=2 cindent
137// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
138// clang-format on
@ IOP_CS_RGB
const dt_aligned_pixel_t f
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1542
@ DT_DEBUG_IMAGEIO
Definition darktable.h:733
#define dt_free(ptr)
Definition darktable.h:456
#define __OMP_PARALLEL_FOR__(...)
Definition darktable.h:258
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
@ TYPE_FLOAT
Definition format.h:46
dt_imageio_retval_t
Definition image.h:78
@ DT_IMAGEIO_OK
Definition image.h:79
@ DT_IMAGEIO_CACHE_FULL
Definition image.h:82
@ DT_IMAGEIO_FILE_CORRUPTED
Definition image.h:81
@ DT_IMAGE_LDR
Definition image.h:109
@ LOADER_WEBP
Definition image.h:237
dt_imageio_retval_t dt_imageio_open_webp(dt_image_t *img, const char *filename, dt_mipmap_buffer_t *mbuf)
void * dt_mipmap_cache_alloc(dt_mipmap_buffer_t *buf, const dt_image_t *img)
int32_t height
Definition image.h:315
dt_image_loader_t loader
Definition image.h:335
int32_t flags
Definition image.h:319
int32_t width
Definition image.h:315
uint32_t profile_size
Definition image.h:341
dt_iop_buffer_dsc_t dsc
Definition image.h:337
uint8_t * profile
Definition image.h:340
char filename[DT_MAX_FILENAME_LEN]
Definition image.h:304
uint32_t filters
Definition format.h:60
unsigned int channels
Definition format.h:54
dt_iop_buffer_type_t datatype
Definition format.h:56