diff options
| author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-09-10 19:11:27 +0200 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-09-10 19:11:27 +0200 | 
| commit | 7e9455b3b15671ff99ed168638c405e2acedb6df (patch) | |
| tree | 444e59ece236e09dc153f665e42160aeb0208c24 /backend/escl/escl_png.c | |
| parent | bc8a517abd2e11e1435f4ef042cfcc8648b62ef7 (diff) | |
| parent | bce41b3c37c2a68e7dab234ce0247755a61ceb40 (diff) | |
Merge branch 'release/debian/1.0.31-1_experimental1' into masterdebian/1.0.31-1_experimental1
Diffstat (limited to 'backend/escl/escl_png.c')
| -rw-r--r-- | backend/escl/escl_png.c | 157 | 
1 files changed, 80 insertions, 77 deletions
| diff --git a/backend/escl/escl_png.c b/backend/escl/escl_png.c index 18f6f35..cf92449 100644 --- a/backend/escl/escl_png.c +++ b/backend/escl/escl_png.c @@ -49,14 +49,15 @@   * \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) +get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)  { -	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  w = 0; +	unsigned int  h = 0; +	int           components = 3; +	unsigned char *surface = NULL;         /* Image data */          unsigned int i = 0;  	png_byte magic[8]; +	SANE_Status status = SANE_STATUS_GOOD;  	// read magic number  	fread (magic, 1, sizeof (magic), scanner->tmp); @@ -64,11 +65,8 @@ get_PNG_data(capabilities_t *scanner, int *w, int *h, int *components)  	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); +                status = SANE_STATUS_INVAL; +                goto close_file;  	}  	// create a png read struct  	png_structp png_ptr = png_create_read_struct @@ -76,12 +74,8 @@ get_PNG_data(capabilities_t *scanner, int *w, int *h, int *components)  	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); +                status = SANE_STATUS_INVAL; +                goto close_file;  	}  	// create a png info struct  	png_infop info_ptr = png_create_info_struct (png_ptr); @@ -89,26 +83,19 @@ get_PNG_data(capabilities_t *scanner, int *w, int *h, int *components)  	{  		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); +                status = SANE_STATUS_INVAL; +                goto close_file;  	}  	// 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; -                } +		if (surface) +		  free (surface);  		DBG( 1, "Escl Png : PNG read error.\n"); -		return (SANE_STATUS_INVAL); +                status = SANE_STATUS_INVAL; +                goto close_file;  	}  	// setup libpng for using standard C fread() function  	//   with our FILE pointer @@ -128,63 +115,79 @@ get_PNG_data(capabilities_t *scanner, int *w, int *h, int *components)  		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); +                DBG(1, "PNG format not supported.\n"); +                status = SANE_STATUS_NO_MEM; +                goto close_file;  	} +      if (color_type ==  PNG_COLOR_TYPE_RGB_ALPHA) -        bps = 4; +        components = 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); +	components = 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*)(&w), +		 (png_uint_32*)(&h), +		 &bit_depth, &color_type, +		 NULL, NULL, NULL); + +    *bps = components; +    // we can now allocate memory for storing pixel data +    surface = (unsigned char *)malloc (sizeof (unsigned char) * w +                    * h * components); +    if (!surface) { +        DBG( 1, "Escl Png : texels Memory allocation problem\n"); +        status = SANE_STATUS_NO_MEM; +	goto close_file; +    } +    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) * h); +    if (!row_pointers) { +        DBG( 1, "Escl Png : row_pointers Memory allocation problem\n"); +        free(surface); +        status = SANE_STATUS_NO_MEM; +	goto close_file; +    } +    for (i = 0; i < h; ++i) +    { +            row_pointers[i] = (png_bytep)(surface + +                            ((h - (i + 1)) * w * components)); +    } +    // read pixel data using row pointers +    png_read_image (png_ptr, row_pointers); + +    // If necessary, trim the image. +    surface = escl_crop_surface(scanner, surface, w, h, components, width, height); +    if (!surface)  { +        DBG( 1, "Escl Png : Surface Memory allocation problem\n"); +        status = SANE_STATUS_NO_MEM; +	goto close_file; +    } + +    free (row_pointers); + +close_file: +    if (scanner->tmp) +        fclose(scanner->tmp);      scanner->tmp = NULL; -    return (SANE_STATUS_GOOD); +    return (status);  }  #else  SANE_Status  get_PNG_data(capabilities_t __sane_unused__ *scanner, -              int __sane_unused__ *w, -              int __sane_unused__ *h, +              int __sane_unused__ *width, +              int __sane_unused__ *height,                int __sane_unused__ *bps)  {      return (SANE_STATUS_INVAL); | 
