33 FILE *file = fopen(filename,
"rb");
34 if (!file)
return NULL;
36 struct jpeg_decompress_struct cinfo;
39 cinfo.err = jpeg_std_error(&jerr.
pub);
43 jpeg_destroy_decompress(&cinfo);
48 jpeg_create_decompress(&cinfo);
49 jpeg_stdio_src(&cinfo, file);
50 jpeg_read_header(&cinfo, TRUE);
51 jpeg_start_decompress(&cinfo);
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;
58 SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 8 * pixel_size, pixel_format);
60 jpeg_finish_decompress(&cinfo);
61 jpeg_destroy_decompress(&cinfo);
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;
72 jpeg_finish_decompress(&cinfo);
73 jpeg_destroy_decompress(&cinfo);
79 bool SaveJPEG(SDL_Renderer *renderer, SDL_Texture *texture,
const char *filename,
int quality) {
80 int width = 0, height = 0;
84 if (SDL_QueryTexture(texture, &format, &access, &width, &height) != 0) {
88 SDL_Texture *old = SDL_GetRenderTarget(renderer);
89 SDL_SetRenderTarget(renderer, texture);
92 SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 24, SDL_PIXELFORMAT_RGB24);
97 if (SDL_RenderReadPixels(renderer,
nullptr, SDL_PIXELFORMAT_RGB24, surface->pixels, surface->pitch) != 0) {
98 SDL_FreeSurface(surface);
102 struct jpeg_compress_struct cinfo;
103 struct jpeg_error_mgr jerr;
104 cinfo.err = jpeg_std_error(&jerr);
105 jpeg_create_compress(&cinfo);
107 FILE* outfile = fopen(filename,
"wb");
109 SDL_FreeSurface(surface);
113 jpeg_stdio_dest(&cinfo, outfile);
115 cinfo.image_width = width;
116 cinfo.image_height = height;
117 cinfo.input_components = 3;
118 cinfo.in_color_space = JCS_RGB;
120 jpeg_set_defaults(&cinfo);
121 jpeg_set_quality(&cinfo, quality, TRUE);
123 jpeg_start_compress(&cinfo, TRUE);
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);
130 jpeg_finish_compress(&cinfo);
131 jpeg_destroy_compress(&cinfo);
133 SDL_FreeSurface(surface);
134 SDL_SetRenderTarget(renderer, old);