File: image.h

package info (click to toggle)
jp2a 1.3.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,028 kB
  • sloc: ansic: 2,230; sh: 160; makefile: 51
file content (351 lines) | stat: -rw-r--r-- 10,420 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
/*! \file
 * \noop Copyright 2006-2016 Christian Stigen Larsen
 * \noop Copyright 2020-2024 Christoph Raitzig
 *
 * \brief Functions that work directly with images.
 *
 * Call decompress_jpeg() or decompress_png() to read an input image from a stream and print it.
 * Which is called does not matter in regards to functionality, if decompress_jpeg() fails decompress_png() is called and vice versa.
 * For efficiency call the function that is most likely to work.
 *
 * All other functions in this file are called by decompress_jpeg() or decompress_png() or one of the functions they call.
 *
 * \author Christian Stigen Larsen
 * \author Christoph Raitzig
 * \copyright Distributed under the GNU General Public License (GPL) v2.
 */

#ifndef INC_JP2A_IMAGE_H
#define INC_JP2A_IMAGE_H

#include "config.h"

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include <stdint.h>

#include "jpeglib.h"
#include "png.h"
#include "webp/decode.h"
#include <setjmp.h>

#include "html.h"

/*! \enum Orientation
 * \brief Image orientation
 *
 * The displayed image orientation can differ from how the image is stored in a file based on Exif metadata.
 */
typedef enum {
	HORIZONTAL,
	MIRROR_HORIZONTAL,
	ROTATE_180,
	MIRROR_VERTICAL,
	MIRROR_HORIZONTAL_ROTATE_90,
	ROTATE_270,
	MIRROR_HORIZONTAL_ROTATE_270,
	ROTATE_90
} Orientation;

/*! \struct Image_
 * \brief Holds a decompressed image.
 *
 * #pixel, #red, #green, #blue, #alpha and #yadds are arrays of size #width * #height.
 */
typedef struct Image_ {
	int width; //!< width
	int height; //!< height
	Orientation orientation; //!< orientation
	int switch_x_y; //!< whether stored x-y-dimensions differ from displayed ones due to a rotation
	int src_width; //!< width in source orientation - differs from width if x and y dimensions are switched
	int src_height; //!< height in source orientation - differs from height if x and y dimensions are switched
	float *pixel; //!< luminosities (i.e. gray values)
	float *red; //!< red part
	float *green; //!< green part
	float *blue; //!< blue part
	float *alpha; //!< opacities
	int *yadds; //!< how many scanlines were used for a pixel, used by normalize()
	float resize_y; //!< Factor by which the output image is resized from the input image in the y dimension (height). For example for an output height of 40 and input height of 80 this equals approximately 0.5.
	float resize_x; //!< Factor by which the output image is resized from the input image in the x dimension (width). For example for an output width of 50 and input height of 100 this equals approximately 2.0.
	int *lookup_resx; //!< where to start and end using pixels of the input image to calculate a pixel of the output image along the x axis
} Image;
/*!
 * \typedef Image
 * \brief See #Image_
 */

/*! \struct my_jpeg_error_mgr
 * \brief This struct is used for custom error handling with libjpeg.
 */
typedef struct my_jpeg_error_mgr {
	struct jpeg_error_mgr pub; //!< libjpeg's error manager
	jmp_buf setjmp_buffer; //!< where to jump to if an error occurs
} my_jpeg_error_mgr;
/*!
 * \typedef my_jpeg_error_mgr
 * \brief See #my_jpeg_error_mgr
 */

/*!
 * \brief Pointer to a #my_jpeg_error_mgr.
 */
typedef struct my_jpeg_error_mgr *my_jpeg_error_ptr;

/*!
 * \brief WebP image data struct
 */
typedef struct {
	uint8_t* data;
	size_t size;
} webp_data;

/*! \struct error_collector
 * \brief Contains and collects errors that occur while decompressing an image.
 *
 * With this struct decompress_jpeg(), decompress_png() and decompress_webp() can be called recursively since #jpeg_status, #png_status and #webp_status can be used to determine whether a previous call failed or not.
 */
typedef struct error_collector {
	my_jpeg_error_mgr *jpeg_error; //!< contains information about a JPEG decompression error
	char *png_error_msg; //!< error message for a PNG decompression error
	char *webp_error_msg; //!< error message for a WebP decompression error
	int jpeg_status; //!< true if an error occurred during JPEG decompression, false otherwise
	int png_status; //!< true if an error occurred during PNG decompression, false otherwise
	int webp_status; //!< true if an error occurred during WebP decompression, false otherwise
} error_collector;
/*!
 * \typedef error_collector
 * \brief See #error_collector
 */

/*!
 * \brief Prints the top margin of an image
 *
 * \param image Image
 * \param f output stream
 */
void print_margin_top(const Image *image, FILE *f);

/*!
 * \brief Prints the bottom margin of an image
 *
 * \param image Image
 * \param f output stream
 */
void print_margin_bottom(const Image *image, FILE *f);

/*!
 * \brief Prints the start margin of an image
 *
 * \param image Image
 * \param f output stream
 */
void print_margin_start(const Image *image, FILE *f);

/*!
 * \brief Prints the top or bottom of a border around an image.
 *
 * \param width width of the output image
 */
void print_border(const int width);

/*!
 * \brief Prints an image.
 *
 * Calls print_image_colors() or print_image_no_colors().
 *
 * \param image the output image
 * \param f the stream to print to
 */
void print_image(Image *image, FILE *f);

/*!
 * \brief Prints an image with color.
 *
 * \param image the output image
 * \param chars the character palette
 * \param f the stream to print to
 */
void print_image_colors(const Image* const image, const int chars, FILE *f);

/*!
 * \brief Prints an image without color.
 *
 * \param image the output image
 * \param chars the character palette
 * \param f the stream to print to
 */
void print_image_no_colors(const Image* const image, const int chars, FILE *f);

/*!
 * \brief Clears the image (i.e. sets all pixels to black, alpha to max)
 *
 * \param i the image
 */
void clear(Image* i);

/*!
 * \brief Normalizes the image.
 *
 * After decompressing the image into RAM the G/RGB values must not be between 0 and 1. The functions normalizes them so that they are.
 *
 * \param i the image
 */
void normalize(Image* i);

/*!
 * \brief Prints a progress bar.
 *
 * \param progress The progress. Between 0 and 1 where 0 is 0% and 1 is 100%
 */
void print_progress(float progress);

/*!
 * \brief Prints some information about the image and how it will be printed.
 *
 * \param jpg contains information about the JPEG image
 * \param orientation image orientation (read from Exif metadata)
 */
void print_info_jpeg(const struct jpeg_decompress_struct* jpg, const Orientation orientation);

/*!
 * \brief Prints some information about the image and how it will be printed.
 *
 * \param png_ptr necessary for calling libpng functions
 * \param info_ptr contains information about the PNG image
 */
void print_info_png(const png_structp png_ptr, const png_infop info_ptr);


/*!
 * \brief Prints some information about the image and how it will be printed.
 *
 * \param config WebP decoding information
 */
void print_info_webp(WebPDecoderConfig* config);

/*!
 * \brief Processes a scanline of a JPEG image.
 *
 * \param jpg contains information about the JPEG image
 * \param scanline the scanline
 * \param i the output image
 */
void process_scanline_jpeg(const struct jpeg_decompress_struct *jpg,
	const JSAMPLE* scanline, Image* i);

/*!
 * \brief Processes a scanline of a PNG image.
 *
 * Supports a bit-depth of 8 and G, GA, RGB and RGBA.
 *
 * \param row scanline (i.e. the row of pixels)
 * \param current_y the current height
 * \param color_components the number of color components (e.g. 4 for RGBA)
 * \param i the output image
 */
void process_scanline_png(const png_bytep row, const int current_y, const int color_components, Image* i);

/*!
 * \brief Frees allocated memory of an image.
 *
 * \param i the image
 */
void free_image(Image* i);

/*!
 * \brief Allocates memory for holding the pixels etc. Sets the width and height.
 *
 * \param i the image
 * \param switch_x_y whether to switch x and y dimensions, this is the case when the stored pixels differ from the displayed pixels due to a rotation
 */
void malloc_image(Image* i, int switch_x_y);

/*!
 * \brief Sets internal values necessary for processing scanlines.
 *
 * \param i the struct to hold the output image
 * \param src_width width of the source image
 * \param src_height height of the source image
 */
void init_image(Image *i, int src_width, int src_height);

/*!
 * \brief Get the image orientation
 *
 * Determine the image orientation from EXIF metadata.
 *
 * Rewinds the file.
 *
 * \param imageFP image file pointer
 */
Orientation get_orientation(FILE *imageFP);

/*!
 * \brief Decompresses and prints an image.
 *
 * Calls decompress_webp() if the image is not a JPEG image.
 * Instead prints errors if there was an error when decompressing this image as JPEG previously.
 *
 * \param fin input stream, has to be seekable
 * \param fout stream to print the image to
 * \param errors contains previous errors and is used to save errors
 */
void decompress_jpeg(FILE *fin, FILE *fout, error_collector *errors);

/*!
 * \brief Callback for errors while decompressing a JPEG image.
 *
 * \param jerr contains information about the error
 */
void jpeg_error_exit(j_common_ptr jerr);

/*!
 * \brief Decompresses and prints an image.
 *
 * Calls decompress_jpeg() if the image is not a PNG image.
 * Instead prints errors if there was an error when decompressing this image as PNG previously.
 *
 * \param fin input stream, has to be seekable
 * \param fout stream to print the image to
 * \param errors contains previous errors and is used to save errors
 */
void decompress_png(FILE *fin, FILE *fout, error_collector *errors);

/*!
 * \brief Read WebP image into a buffer
 *
 * \param fp input stream
 */
webp_data* get_webp_data(FILE *fp);

/*!
 * \brief Free WebP image buffer
 * 
 * \param data WebP data
 */
void free_webp_data(webp_data* data);

/*!
 * \brief Decompresses and prints an image.
 *
 * Calls decompress_png() if the image is not a WebP image.
 * Instead prints errors if there was an error when decompressing this image as WebP previously.
 *
 * \param fin input stream, has to be seekable
 * \param fout stream to print the image to
 * \param errors contains previous errors and is used to save errors
 */
void decompress_webp(FILE *fp, FILE *fout, error_collector *errors);

/*!
 * \brief Prints errors.
 *
 * Checks what errors have occurred and prints their error messages.
 *
 * \param errors the collected errors
 */
void print_errors(error_collector *errors);

#endif