diff options
| author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-02-02 17:13:42 +0100 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-02-02 17:13:42 +0100 | 
| commit | 3dade5db2a37543f19f0967901d8d80a52a1e459 (patch) | |
| tree | 808b2499b54563b3290f34d70d159b1024310873 /backend/escl/escl_png.c | |
| parent | 5bb4cf12855ec0151de15d6c5a2354ff08766957 (diff) | |
| parent | ffa8801644a7d53cc1c785e3450f794c07a14eb0 (diff) | |
Update upstream source from tag 'upstream/1.0.29'
Update to upstream version '1.0.29'
with Debian dir 2d358af604988ebe4348e38096245d66036fe5ed
Diffstat (limited to 'backend/escl/escl_png.c')
| -rw-r--r-- | backend/escl/escl_png.c | 193 | 
1 files changed, 193 insertions, 0 deletions
| diff --git a/backend/escl/escl_png.c b/backend/escl/escl_png.c new file mode 100644 index 0000000..18f6f35 --- /dev/null +++ b/backend/escl/escl_png.c @@ -0,0 +1,193 @@ +/* sane - Scanner Access Now Easy. + +   Copyright (C) 2019 Touboul Nathane +   Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + +   This file is part of the SANE package. + +   SANE is free software; you can redistribute it and/or modify it under +   the terms of the GNU General Public License as published by the Free +   Software Foundation; either version 3 of the License, or (at your +   option) any later version. + +   SANE 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 General Public License +   for more details. + +   You should have received a copy of the GNU General Public License +   along with sane; see the file COPYING.  If not, write to the Free +   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +   This file implements a SANE backend for eSCL scanners.  */ + +#define DEBUG_DECLARE_ONLY +#include "../include/sane/config.h" + +#include "escl.h" + +#include "../include/sane/sanei.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if(defined HAVE_LIBPNG) +#include <png.h> +#endif + +#include <setjmp.h> + + +#if(defined HAVE_LIBPNG) + +/** + * \fn SANE_Status escl_sane_decompressor(escl_sane_t *handler) + * \brief Function that aims to decompress the png image to SANE be able to read the image. + *        This function is called in the "sane_read" function. + * + * \return SANE_STATUS_GOOD (if everything is OK, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) + */ +SANE_Status +get_PNG_data(capabilities_t *scanner, int *w, int *h, int *components) +{ +	unsigned int  width = 0;           /* largeur */ +	unsigned int  height = 0;          /* hauteur */ +	int           bps = 3;  /* composantes d'un texel */ +	unsigned char *texels = NULL;         /* données de l'image */ +        unsigned int i = 0; +	png_byte magic[8]; + +	// read magic number +	fread (magic, 1, sizeof (magic), scanner->tmp); +	// check for valid magic number +	if (!png_check_sig (magic, sizeof (magic))) +	{ +		DBG( 1, "Escl Png : PNG error is not a valid PNG image!\n"); +                if (scanner->tmp) { +                   fclose(scanner->tmp); +                   scanner->tmp = NULL; +                } +		return (SANE_STATUS_INVAL); +	} +	// create a png read struct +	png_structp png_ptr = png_create_read_struct +		(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); +	if (!png_ptr) +	{ +		DBG( 1, "Escl Png : PNG error create a png read struct\n"); +                if (scanner->tmp) +                if (scanner->tmp) { +                   fclose(scanner->tmp); +                   scanner->tmp = NULL; +                } +		return (SANE_STATUS_INVAL); +	} +	// create a png info struct +	png_infop info_ptr = png_create_info_struct (png_ptr); +	if (!info_ptr) +	{ +		DBG( 1, "Escl Png : PNG error create a png info struct\n"); +		png_destroy_read_struct (&png_ptr, NULL, NULL); +                if (scanner->tmp) { +                   fclose(scanner->tmp); +                   scanner->tmp = NULL; +                } +		return (SANE_STATUS_INVAL); +	} +	// initialize the setjmp for returning properly after a libpng +	//   error occured +	if (setjmp (png_jmpbuf (png_ptr))) +	{ +		png_destroy_read_struct (&png_ptr, &info_ptr, NULL); +		if (texels) +		  free (texels); +        fprintf(stderr,"PNG read error.\n"); +                if (scanner->tmp) { +                   fclose(scanner->tmp); +                   scanner->tmp = NULL; +                } +		DBG( 1, "Escl Png : PNG read error.\n"); +		return (SANE_STATUS_INVAL); +	} +	// setup libpng for using standard C fread() function +	//   with our FILE pointer +	png_init_io (png_ptr, scanner->tmp); +	// tell libpng that we have already read the magic number +	png_set_sig_bytes (png_ptr, sizeof (magic)); + +	// read png info +	png_read_info (png_ptr, info_ptr); + +	int bit_depth, color_type; +	// get some usefull information from header +	bit_depth = png_get_bit_depth (png_ptr, info_ptr); +	color_type = png_get_color_type (png_ptr, info_ptr); +	// convert index color images to RGB images +	if (color_type == PNG_COLOR_TYPE_PALETTE) +		png_set_palette_to_rgb (png_ptr); +	else if (color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA) +	{ +        fprintf(stderr,"PNG format not supported.\n"); +                if (scanner->tmp) { +                   fclose(scanner->tmp); +                   scanner->tmp = NULL; +                } +		return (SANE_STATUS_INVAL); +	} +    if (color_type ==  PNG_COLOR_TYPE_RGB_ALPHA) +        bps = 4; +    else +	    bps = 3; +	if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) +		png_set_tRNS_to_alpha (png_ptr); +	if (bit_depth == 16) +		png_set_strip_16 (png_ptr); +	else if (bit_depth < 8) +		png_set_packing (png_ptr); +	// update info structure to apply transformations +	png_read_update_info (png_ptr, info_ptr); +	// retrieve updated information +	png_get_IHDR (png_ptr, info_ptr, +			(png_uint_32*)(&width), +			(png_uint_32*)(&height), +			&bit_depth, &color_type, +			NULL, NULL, NULL); + +    *w = (int)width; +    *h = (int)height; +    *components = bps; +	// we can now allocate memory for storing pixel data +	texels = (unsigned char *)malloc (sizeof (unsigned char) * width +			* height * bps); +	png_bytep *row_pointers; +	// setup a pointer array.  Each one points at the begening of a row. +	row_pointers = (png_bytep *)malloc (sizeof (png_bytep) * height); +	for (i = 0; i < height; ++i) +	{ +		row_pointers[i] = (png_bytep)(texels + +				((height - (i + 1)) * width * bps)); +	} +	// read pixel data using row pointers +	png_read_image (png_ptr, row_pointers); +	// we don't need row pointers anymore +	scanner->img_data = texels; +    scanner->img_size = (int)(width * height * bps); +    scanner->img_read = 0; +	free (row_pointers); +    fclose(scanner->tmp); +    scanner->tmp = NULL; +    return (SANE_STATUS_GOOD); +} +#else + +SANE_Status +get_PNG_data(capabilities_t __sane_unused__ *scanner, +              int __sane_unused__ *w, +              int __sane_unused__ *h, +              int __sane_unused__ *bps) +{ +    return (SANE_STATUS_INVAL); +} + +#endif | 
