libmx2 2.2.1
C++20 multimedia and game-engine library (SDL2 / OpenGL / Vulkan)
Loading...
Searching...
No Matches
jpeg.cpp
Go to the documentation of this file.
1/**
2 * @file jpeg.cpp
3 * @brief Implementation of jpeg::LoadJPEG and jpeg::SaveJPEG utilities.
4 */
5#ifdef __EMSCRIPTEN__
6#include"config.hpp"
7#else
8#include"config.h"
9#endif
10
11#ifdef WITH_JPEG
12#include <stdio.h>
13#include <jpeglib.h>
14#include <setjmp.h>
15#include "SDL.h"
16
17namespace jpeg {
18
19 struct my_error_mgr {
20 struct jpeg_error_mgr pub;
22 };
23
24 typedef struct my_error_mgr *my_error_ptr;
25
26 void my_error_exit(j_common_ptr cinfo) {
27 my_error_ptr myerr = (my_error_ptr)cinfo->err;
28 (*cinfo->err->output_message)(cinfo);
29 longjmp(myerr->setjmp_buffer, 1);
30 }
31
32 SDL_Surface *LoadJPEG(const char *filename) {
33 FILE *file = fopen(filename, "rb");
34 if (!file) return NULL;
35
36 struct jpeg_decompress_struct cinfo;
37 struct my_error_mgr jerr;
38
39 cinfo.err = jpeg_std_error(&jerr.pub);
40 jerr.pub.error_exit = my_error_exit;
41
42 if (setjmp(jerr.setjmp_buffer)) {
43 jpeg_destroy_decompress(&cinfo);
44 fclose(file);
45 return NULL;
46 }
47
48 jpeg_create_decompress(&cinfo);
49 jpeg_stdio_src(&cinfo, file);
50 jpeg_read_header(&cinfo, TRUE);
51 jpeg_start_decompress(&cinfo);
52
53 int width = cinfo.output_width;
54 int height = cinfo.output_height;
55 int pixel_size = cinfo.output_components;
56 Uint32 pixel_format = (pixel_size == 3) ? SDL_PIXELFORMAT_RGB24 : SDL_PIXELFORMAT_RGBA32;
57
58 SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 8 * pixel_size, pixel_format);
59 if (!surface) {
60 jpeg_finish_decompress(&cinfo);
61 jpeg_destroy_decompress(&cinfo);
62 fclose(file);
63 return NULL;
64 }
65
66 unsigned char *row_pointer = (unsigned char *)surface->pixels;
67 while (cinfo.output_scanline < cinfo.output_height) {
68 jpeg_read_scanlines(&cinfo, &row_pointer, 1);
69 row_pointer += surface->pitch;
70 }
71
72 jpeg_finish_decompress(&cinfo);
73 jpeg_destroy_decompress(&cinfo);
74 fclose(file);
75
76 return surface;
77 }
78
79 bool SaveJPEG(SDL_Renderer *renderer, SDL_Texture *texture, const char *filename, int quality) {
80 int width = 0, height = 0;
81 Uint32 format = 0;
82 int access = 0;
83
84 if (SDL_QueryTexture(texture, &format, &access, &width, &height) != 0) {
85 return false;
86 }
87
88 SDL_Texture *old = SDL_GetRenderTarget(renderer);
89 SDL_SetRenderTarget(renderer, texture);
90
91
92 SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 24, SDL_PIXELFORMAT_RGB24);
93 if (!surface) {
94 return false;
95 }
96
97 if (SDL_RenderReadPixels(renderer, nullptr, SDL_PIXELFORMAT_RGB24, surface->pixels, surface->pitch) != 0) {
98 SDL_FreeSurface(surface);
99 return false;
100 }
101
102 struct jpeg_compress_struct cinfo;
103 struct jpeg_error_mgr jerr;
104 cinfo.err = jpeg_std_error(&jerr);
105 jpeg_create_compress(&cinfo);
106
107 FILE* outfile = fopen(filename, "wb");
108 if (!outfile) {
109 SDL_FreeSurface(surface);
110 return false;
111 }
112
113 jpeg_stdio_dest(&cinfo, outfile);
114
115 cinfo.image_width = width;
116 cinfo.image_height = height;
117 cinfo.input_components = 3;
118 cinfo.in_color_space = JCS_RGB;
119
120 jpeg_set_defaults(&cinfo);
121 jpeg_set_quality(&cinfo, quality, TRUE);
122
123 jpeg_start_compress(&cinfo, TRUE);
124
125 JSAMPROW row_pointer;
126 while (cinfo.next_scanline < cinfo.image_height) {
127 row_pointer = (JSAMPROW)((Uint8*)surface->pixels + cinfo.next_scanline * surface->pitch);
128 jpeg_write_scanlines(&cinfo, &row_pointer, 1);
129 }
130 jpeg_finish_compress(&cinfo);
131 jpeg_destroy_compress(&cinfo);
132 fclose(outfile);
133 SDL_FreeSurface(surface);
134 SDL_SetRenderTarget(renderer, old);
135 return true;
136 }
137}
138#endif
Compile-time feature flags and version macros for libmx.
Utilities for loading and saving JPEG images.
Definition jpeg.cpp:17
SDL_Surface * LoadJPEG(const char *filename)
Load a JPEG file into an SDL_Surface.
Definition jpeg.cpp:32
struct my_error_mgr * my_error_ptr
Definition jpeg.cpp:24
void my_error_exit(j_common_ptr cinfo)
Definition jpeg.cpp:26
bool SaveJPEG(SDL_Renderer *renderer, SDL_Texture *texture, const char *filename, int quality)
Save an SDL_Texture to a JPEG file.
Definition jpeg.cpp:79
struct jpeg_error_mgr pub
Definition jpeg.cpp:20
jmp_buf setjmp_buffer
Definition jpeg.cpp:21