Add code to load jpegs

This lets us avoid gdk-pixbuf for loading
textures from the common image formats.

As a consequence, we are now linking against libjpeg.
This commit is contained in:
Matthias Clasen
2021-09-09 23:52:39 -04:00
parent f89be80562
commit 6a83d38e7b
4 changed files with 172 additions and 1 deletions

127
gdk/loaders/gdkjpeg.c Normal file
View File

@@ -0,0 +1,127 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2021 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkjpegprivate.h"
#include "gdktexture.h"
#include "gdkmemorytextureprivate.h"
#include <jpeglib.h>
#include <jerror.h>
#include <setjmp.h>
/* {{{ Error handling */
/* No sigsetjmp on Windows */
#ifndef HAVE_SIGSETJMP
#define sigjmp_buf jmp_buf
#define sigsetjmp(jb, x) setjmp(jb)
#define siglongjmp longjmp
#endif
struct error_handler_data {
struct jpeg_error_mgr pub;
sigjmp_buf setjmp_buffer;
GError **error;
};
static void
fatal_error_handler (j_common_ptr cinfo)
{
struct error_handler_data *errmgr;
errmgr = (struct error_handler_data *) cinfo->err;
siglongjmp (errmgr->setjmp_buffer, 1);
g_assert_not_reached ();
}
static void
output_message_handler (j_common_ptr cinfo)
{
/* do nothing */
}
/* }}} */
/* {{{ Public API */
GdkTexture *
gdk_load_jpeg (GBytes *input_bytes,
GError **error)
{
struct jpeg_decompress_struct info;
struct error_handler_data jerr;
struct jpeg_error_mgr err;
int width, height;
int size;
unsigned char *data;
unsigned char *row[1];
GBytes *bytes;
GdkTexture *texture;
info.err = jpeg_std_error (&jerr.pub);
jerr.pub.error_exit = fatal_error_handler;
jerr.pub.output_message = output_message_handler;
jerr.error = error;
if (sigsetjmp (jerr.setjmp_buffer, 1))
{
jpeg_destroy_decompress (&info);
return NULL;
}
info.err = jpeg_std_error (&err);
jpeg_create_decompress (&info);
jpeg_mem_src (&info,
g_bytes_get_data (input_bytes, NULL),
g_bytes_get_size (input_bytes));
jpeg_read_header (&info, TRUE);
jpeg_start_decompress (&info);
width = info.output_width;
height = info.output_height;
size = width * height * 3;
data = g_malloc (size);
while (info.output_scanline < info.output_height)
{
row[0] = (unsigned char *)(&data[3 *info.output_width * info.output_scanline]);
jpeg_read_scanlines (&info, row, 1);
}
jpeg_finish_decompress (&info);
jpeg_destroy_decompress (&info);
bytes = g_bytes_new_take (data, size);
texture = gdk_memory_texture_new (width, height,
GDK_MEMORY_R8G8B8,
bytes, width * 3);
g_bytes_unref (bytes);
return texture;
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */

View File

@@ -0,0 +1,29 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2021 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_JPEG_PRIVATE_H__
#define __GDK_JPEG_PRIVATE_H__
#include "gdkmemorytexture.h"
#include <gio/gio.h>
#define JPEG_SIGNATURE "\xff\xd8"
GdkTexture *gdk_load_jpeg (GBytes *bytes,
GError **error);
#endif

View File

@@ -53,6 +53,7 @@ gdk_public_sources = files([
'gdkdragsurface.c',
'loaders/gdkpng.c',
'loaders/gdktiff.c',
'loaders/gdkjpeg.c',
])
gdk_public_headers = files([
@@ -258,7 +259,7 @@ endif
libgdk = static_library('gdk',
sources: [gdk_sources, gdk_backends_gen_headers, gdkconfig],
dependencies: gdk_deps + [libgtk_css_dep, png_dep, tiff_dep],
dependencies: gdk_deps + [libgtk_css_dep, png_dep, tiff_dep, jpeg_dep],
link_with: [libgtk_css],
include_directories: [confinc, gdkx11_inc, wlinc],
c_args: libgdk_c_args + common_cflags,

View File

@@ -207,6 +207,17 @@ foreach func : check_functions
endif
endforeach
# We use links() because sigsetjmp() is often a macro hidden behind other macros
cdata.set('HAVE_SIGSETJMP',
cc.links('''#define _POSIX_SOURCE
#include <setjmp.h>
int main (void) {
sigjmp_buf env;
sigsetjmp (env, 0);
return 0;
}''', name: 'sigsetjmp'),
)
# Check for __uint128_t (gcc) by checking for 128-bit division
uint128_t_src = '''int main() {
static __uint128_t v1 = 100;
@@ -395,6 +406,9 @@ png_dep = dependency('libpng',
tiff_dep = dependency('libtiff-4',
fallback: ['libtiff', 'libtiff4_dep'],
required: true)
jpeg_dep = dependency('libjpeg',
fallback: ['libjpeg-turbo', 'jpeg_dep'],
required: true)
epoxy_dep = dependency('epoxy', version: epoxy_req,
fallback: ['libepoxy', 'libepoxy_dep'])