GCC Code Coverage Report


Directory: src/gate/
File: src/gate/graphics/imageformats.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 0 53 0.0%
Functions: 0 6 0.0%
Branches: 0 32 0.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28 #include "gate/graphics/imageformats.h"
29 #include "gate/results.h"
30 #include "gate/files.h"
31 #include "gate/graphics/bitmapimages.h"
32 #include "gate/graphics/jpegimages.h"
33 #include "gate/graphics/pixmapimages.h"
34 #include "gate/graphics/pngimages.h"
35 #include "gate/graphics/gifimages.h"
36
37 struct ext_mapping
38 {
39 gate_enumint_t id;
40 char const* ext;
41 gate_image_reader_t reader;
42 gate_image_writer_t writer;
43 };
44
45 static struct ext_mapping const gate_ext_mapping[] =
46 {
47 { GATE_IMAGEFORMAT_BITMAP, "bmp", &gate_bitmapimage_load, &gate_bitmapimage_save },
48 { GATE_IMAGEFORMAT_PIXMAP, "xpm", &gate_pixmapimage_load, &gate_pixmapimage_save },
49 { GATE_IMAGEFORMAT_JPEG, "jpg", &gate_jpegimage_load, &gate_jpegimage_save },
50 { GATE_IMAGEFORMAT_JPEG, "jpeg", &gate_jpegimage_load, &gate_jpegimage_save },
51 { GATE_IMAGEFORMAT_GIF, "gif", &gate_gifimage_load, &gate_gifimage_save },
52 { GATE_IMAGEFORMAT_PNG, "png", &gate_pngimage_load, &gate_pngimage_save }
53 };
54 static gate_size_t const gate_ext_mapping_count = sizeof(gate_ext_mapping) / sizeof(gate_ext_mapping[0]);
55
56 gate_enumint_t gate_imageformat_parse_file_extension(gate_string_t const* file_ext)
57 {
58 gate_size_t ndx;
59 char const* ext;
60 gate_size_t ext_len;
61 for (ndx = 0; ndx != gate_ext_mapping_count; ++ndx)
62 {
63 ext = gate_ext_mapping[ndx].ext;
64 ext_len = gate_str_length(ext);
65 if (gate_str_compare(file_ext->str, file_ext->length, ext, ext_len) == 0)
66 {
67 return gate_ext_mapping[ndx].id;
68 }
69 if (gate_str_ends_with_ic(file_ext->str, file_ext->length, ext, ext_len))
70 {
71 if (file_ext->str[file_ext->length - ext_len - 1] == '.')
72 {
73 return gate_ext_mapping[ndx].id;
74 }
75 }
76 }
77 return GATE_IMAGEFORMAT_UNKNOWN;
78 }
79 char const* gate_imageformat_get_file_extension(gate_enumint_t image_format)
80 {
81 gate_size_t ndx;
82 for (ndx = 0; ndx != gate_ext_mapping_count; ++ndx)
83 {
84 if (gate_ext_mapping[ndx].id == image_format)
85 {
86 return gate_ext_mapping[ndx].ext;
87 }
88 }
89 return NULL;
90 }
91
92 gate_result_t gate_imageformat_load(gate_enumint_t image_format, gate_stream_t* srcstream, gate_rasterimage_t* image, gate_enumint_t flags)
93 {
94 gate_result_t result = GATE_RESULT_NOTSUPPORTED;
95 gate_size_t ndx;
96 for (ndx = 0; ndx != gate_ext_mapping_count; ++ndx)
97 {
98 if (gate_ext_mapping[ndx].id == image_format)
99 {
100 result = gate_ext_mapping[ndx].reader(srcstream, image, flags);
101 break;
102 }
103 }
104 return result;
105 }
106
107 gate_result_t gate_imageformat_save(gate_enumint_t image_format, gate_rasterimage_t const* image, gate_stream_t* deststream, gate_enumint_t flags)
108 {
109 gate_result_t result = GATE_RESULT_FAILED;
110 gate_size_t ndx;
111 for (ndx = 0; ndx != gate_ext_mapping_count; ++ndx)
112 {
113 if (gate_ext_mapping[ndx].id == image_format)
114 {
115 result = gate_ext_mapping[ndx].writer(image, deststream, flags);
116 break;
117 }
118 }
119 return result;
120 }
121
122 gate_result_t gate_imageformat_load_file(gate_string_t const* file_path, gate_rasterimage_t* image, gate_enumint_t flags)
123 {
124 gate_result_t result;
125 gate_int32_t file_id = gate_imageformat_parse_file_extension(file_path);
126 gate_controlstream_t* filestream = NULL;
127 do
128 {
129 if (file_id == GATE_IMAGEFORMAT_UNKNOWN)
130 {
131 result = GATE_RESULT_NOTSUPPORTED;
132 break;
133 }
134 result = gate_file_openstream(file_path, GATE_STREAM_OPEN_READ, &filestream);
135 GATE_BREAK_IF_FAILED(result);
136 result = gate_imageformat_load(file_id, (gate_stream_t*)filestream, image, flags);
137 } while (0);
138
139 if (filestream != NULL)
140 {
141 gate_object_release(filestream);
142 }
143 return result;
144 }
145 gate_result_t gate_imageformat_save_file(gate_string_t const* file_path, gate_rasterimage_t const* image, gate_enumint_t flags)
146 {
147 gate_result_t result;
148 gate_int32_t file_id = gate_imageformat_parse_file_extension(file_path);
149 gate_filestream_t* filestream = NULL;
150 do
151 {
152 if (file_id == GATE_IMAGEFORMAT_UNKNOWN)
153 {
154 result = GATE_RESULT_NOTSUPPORTED;
155 break;
156 }
157 result = gate_file_openstream(file_path, GATE_STREAM_OPEN_WRITE, &filestream);
158 GATE_BREAK_IF_FAILED(result);
159 result = gate_imageformat_save(file_id, image, (gate_stream_t*)filestream, flags);
160 } while (0);
161
162 if (filestream != NULL)
163 {
164 gate_object_release(filestream);
165 }
166 return result;
167 }
168