Blame test/raw_decode.c

Packit 7838c8
/* $Id: raw_decode.c,v 1.7 2015-08-16 20:08:21 bfriesen Exp $ */
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Copyright (c) 2012, Frank Warmerdam <warmerdam@pobox.com>
Packit 7838c8
 *
Packit 7838c8
 * Permission to use, copy, modify, distribute, and sell this software and 
Packit 7838c8
 * its documentation for any purpose is hereby granted without fee, provided
Packit 7838c8
 * that (i) the above copyright notices and this permission notice appear in
Packit 7838c8
 * all copies of the software and related documentation, and (ii) the names of
Packit 7838c8
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
Packit 7838c8
 * publicity relating to the software without the specific, prior written
Packit 7838c8
 * permission of Sam Leffler and Silicon Graphics.
Packit 7838c8
 * 
Packit 7838c8
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
Packit 7838c8
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
Packit 7838c8
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
Packit 7838c8
 * 
Packit 7838c8
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
Packit 7838c8
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
Packit 7838c8
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit 7838c8
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
Packit 7838c8
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
Packit 7838c8
 * OF THIS SOFTWARE.
Packit 7838c8
 */
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * TIFF Library
Packit 7838c8
 *
Packit 7838c8
 * The objective of this test suite is to test the JPEGRawDecode() 
Packit 7838c8
 * interface via TIFReadEncodedTile().  This function with YCbCr subsampling
Packit 7838c8
 * is a frequent source of bugs. 
Packit 7838c8
 */
Packit 7838c8
Packit 7838c8
#include "tif_config.h"
Packit 7838c8
Packit 7838c8
#include <stdio.h>
Packit 7838c8
#include <stdlib.h>
Packit 7838c8
#include <string.h>
Packit 7838c8
#ifdef HAVE_UNISTD_H 
Packit 7838c8
# include <unistd.h> 
Packit 7838c8
#endif 
Packit 7838c8
Packit 7838c8
#include "tiffio.h"
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
  Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
Packit 7838c8
  not defined.  Unfortunately, the MinGW and Borland compilers include
Packit 7838c8
  a typedef for INT32, which causes a conflict.  MSVC does not include
Packit 7838c8
  a conficting typedef given the headers which are included.
Packit 7838c8
*/
Packit 7838c8
#if defined(__BORLANDC__) || defined(__MINGW32__)
Packit 7838c8
# define XMD_H 1
Packit 7838c8
#endif
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
   The windows RPCNDR.H file defines boolean, but defines it with the
Packit 7838c8
   unsigned char size.  You should compile JPEG library using appropriate
Packit 7838c8
   definitions in jconfig.h header, but many users compile library in wrong
Packit 7838c8
   way. That causes errors of the following type:
Packit 7838c8
Packit 7838c8
   "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432,
Packit 7838c8
   caller expects 464"
Packit 7838c8
Packit 7838c8
   For such users we wil fix the problem here. See install.doc file from
Packit 7838c8
   the JPEG library distribution for details.
Packit 7838c8
*/
Packit 7838c8
Packit 7838c8
/* Define "boolean" as unsigned char, not int, per Windows custom. */
Packit 7838c8
#if defined(__WIN32__) && !defined(__MINGW32__)
Packit 7838c8
# ifndef __RPCNDR_H__            /* don't conflict if rpcndr.h already read */
Packit 7838c8
   typedef unsigned char boolean;
Packit 7838c8
# endif
Packit 7838c8
# define HAVE_BOOLEAN            /* prevent jmorecfg.h from redefining it */
Packit 7838c8
#endif
Packit 7838c8
#include "jpeglib.h" /* Needed for JPEG_LIB_VERSION */
Packit 7838c8
Packit 7838c8
static unsigned char cluster_0[] = { 0, 0, 2, 0, 138, 139 };
Packit 7838c8
static unsigned char cluster_64[] = { 0, 0, 9, 6, 134, 119 };
Packit 7838c8
static unsigned char cluster_128[] = { 44, 40, 63, 59, 230, 95 };
Packit 7838c8
Packit 7838c8
static int check_cluster( int cluster, unsigned char *buffer, unsigned char *expected_cluster ) {
Packit 7838c8
	unsigned char *target = buffer + cluster*6;
Packit 7838c8
Packit 7838c8
	if (memcmp(target, expected_cluster, 6) == 0) {
Packit 7838c8
		return 0;
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	fprintf( stderr, "Cluster %d did not match expected results.\n", cluster );
Packit 7838c8
	fprintf( stderr, 
Packit 7838c8
		 "Expect: %3d %3d   %3d   %3d\n"
Packit 7838c8
		 "        %3d %3d\n", 
Packit 7838c8
		 expected_cluster[0], expected_cluster[1],
Packit 7838c8
		 expected_cluster[4], expected_cluster[5],
Packit 7838c8
		 expected_cluster[2], expected_cluster[3] );
Packit 7838c8
	fprintf( stderr, 
Packit 7838c8
		 "   Got: %3d %3d   %3d   %3d\n"
Packit 7838c8
		 "        %3d %3d\n", 
Packit 7838c8
		 target[0], target[1], 
Packit 7838c8
		 target[4], target[5],
Packit 7838c8
		 target[2], target[3] );
Packit 7838c8
	return 1;
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
static int check_rgb_pixel( int pixel,
Packit 7838c8
			    int min_red, int max_red,
Packit 7838c8
			    int min_green, int max_green,
Packit 7838c8
			    int min_blue, int max_blue,
Packit 7838c8
			    unsigned char *buffer ) {
Packit 7838c8
	unsigned char *rgb = buffer + 3 * pixel;
Packit 7838c8
	
Packit 7838c8
	if( rgb[0] >= min_red && rgb[0] <= max_red &&
Packit 7838c8
	    rgb[1] >= min_green && rgb[1] <= max_green &&
Packit 7838c8
	    rgb[2] >= min_blue && rgb[2] <= max_blue ) {
Packit 7838c8
		return 0;
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	fprintf( stderr, "Pixel %d did not match expected results.\n", pixel );
Packit 7838c8
	fprintf( stderr, "Got R=%d (expected %d..%d), G=%d (expected %d..%d), B=%d (expected %d..%d)\n",
Packit 7838c8
		 rgb[0], min_red, max_red,
Packit 7838c8
		 rgb[1], min_green, max_green,
Packit 7838c8
		 rgb[2], min_blue, max_blue );
Packit 7838c8
	return 1;
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
static int check_rgba_pixel( int pixel,
Packit 7838c8
			     int min_red, int max_red,
Packit 7838c8
			     int min_green, int max_green,
Packit 7838c8
			     int min_blue, int max_blue,
Packit 7838c8
			     int min_alpha, int max_alpha,
Packit 7838c8
			     uint32 *buffer ) {
Packit 7838c8
	/* RGBA images are upside down - adjust for normal ordering */
Packit 7838c8
	int adjusted_pixel = pixel % 128 + (127 - (pixel/128)) * 128;
Packit 7838c8
	uint32 rgba = buffer[adjusted_pixel];
Packit 7838c8
Packit 7838c8
	if( TIFFGetR(rgba) >= (uint32) min_red &&
Packit 7838c8
	    TIFFGetR(rgba) <= (uint32) max_red &&
Packit 7838c8
	    TIFFGetG(rgba) >= (uint32) min_green &&
Packit 7838c8
	    TIFFGetG(rgba) <= (uint32) max_green &&
Packit 7838c8
	    TIFFGetB(rgba) >= (uint32) min_blue &&
Packit 7838c8
	    TIFFGetB(rgba) <= (uint32) max_blue &&
Packit 7838c8
	    TIFFGetA(rgba) >= (uint32) min_alpha &&
Packit 7838c8
	    TIFFGetA(rgba) <= (uint32) max_alpha ) {
Packit 7838c8
		return 0;
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	fprintf( stderr, "Pixel %d did not match expected results.\n", pixel );
Packit 7838c8
	fprintf( stderr, "Got R=%d (expected %d..%d), G=%d (expected %d..%d), B=%d (expected %d..%d), A=%d (expected %d..%d)\n",
Packit 7838c8
		 TIFFGetR(rgba), min_red, max_red,
Packit 7838c8
		 TIFFGetG(rgba), min_green, max_green,
Packit 7838c8
		 TIFFGetB(rgba), min_blue, max_blue,
Packit 7838c8
		 TIFFGetA(rgba), min_alpha, max_alpha );
Packit 7838c8
	return 1;
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
int
Packit 7838c8
main(int argc, char **argv)
Packit 7838c8
{
Packit 7838c8
	TIFF		*tif;
Packit 7838c8
	static const char *srcfilerel = "images/quad-tile.jpg.tiff";
Packit 7838c8
	char *srcdir = NULL;
Packit 7838c8
	char srcfile[1024];
Packit 7838c8
	unsigned short h, v;
Packit 7838c8
	int status;
Packit 7838c8
	unsigned char *buffer;
Packit 7838c8
	uint32 *rgba_buffer;
Packit 7838c8
	tsize_t sz, szout;
Packit 7838c8
	unsigned int pixel_status = 0;
Packit 7838c8
Packit 7838c8
        (void) argc;
Packit 7838c8
        (void) argv;
Packit 7838c8
Packit 7838c8
	if ((srcdir = getenv("srcdir")) == NULL) {
Packit 7838c8
		srcdir = ".";
Packit 7838c8
	}
Packit 7838c8
	if ((strlen(srcdir) + 1 + strlen(srcfilerel)) >= sizeof(srcfile)) {
Packit 7838c8
		fprintf( stderr, "srcdir too long %s\n", srcdir);
Packit 7838c8
		exit( 1 );
Packit 7838c8
	}
Packit 7838c8
	strcpy(srcfile,srcdir);
Packit 7838c8
	strcat(srcfile,"/");
Packit 7838c8
	strcat(srcfile,srcfilerel);
Packit 7838c8
Packit 7838c8
	tif = TIFFOpen(srcfile,"r");
Packit 7838c8
	if ( tif == NULL ) {
Packit 7838c8
		fprintf( stderr, "Could not open %s\n", srcfile);
Packit 7838c8
		exit( 1 );
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	status = TIFFGetField(tif,TIFFTAG_YCBCRSUBSAMPLING, &h, &v);
Packit 7838c8
	if ( status == 0 || h != 2 || v != 2) {
Packit 7838c8
		fprintf( stderr, "Could not retrieve subsampling tag.\n" );
Packit 7838c8
		exit(1);
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * What is the appropriate size of a YCbCr encoded tile?
Packit 7838c8
	 */
Packit 7838c8
	sz = TIFFTileSize(tif);
Packit 7838c8
	if( sz != 24576) {
Packit 7838c8
		fprintf(stderr, "tiles are %d bytes\n", (int)sz);
Packit 7838c8
		exit(1);
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	buffer = (unsigned char *) malloc(sz);
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * Read a tile in decompressed form, but still YCbCr subsampled.
Packit 7838c8
	 */
Packit 7838c8
	szout = TIFFReadEncodedTile(tif,9,buffer,sz);
Packit 7838c8
	if (szout != sz) {
Packit 7838c8
		fprintf( stderr, 
Packit 7838c8
			 "Did not get expected result code from TIFFReadEncodedTile()(%d instead of %d)\n", 
Packit 7838c8
			 (int) szout, (int) sz );
Packit 7838c8
		return 1;
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	if( check_cluster( 0, buffer, cluster_0 )
Packit 7838c8
	    || check_cluster( 64, buffer, cluster_64 )
Packit 7838c8
	    || check_cluster( 128, buffer, cluster_128 ) ) {
Packit 7838c8
		exit(1);
Packit 7838c8
	}
Packit 7838c8
	free(buffer);
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * Read a tile using the built-in conversion to RGB format provided by the JPEG library.
Packit 7838c8
	 */
Packit 7838c8
	TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
Packit 7838c8
Packit 7838c8
	sz = TIFFTileSize(tif);
Packit 7838c8
	if( sz != 128*128*3) {
Packit 7838c8
		fprintf(stderr, "tiles are %d bytes\n", (int)sz);
Packit 7838c8
		exit(1);
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	buffer = (unsigned char *) malloc(sz);
Packit 7838c8
Packit 7838c8
	szout = TIFFReadEncodedTile(tif,9,buffer,sz);
Packit 7838c8
	if (szout != sz) {
Packit 7838c8
		fprintf( stderr, 
Packit 7838c8
			 "Did not get expected result code from TIFFReadEncodedTile()(%d instead of %d)\n", 
Packit 7838c8
			 (int) szout, (int) sz );
Packit 7838c8
		return 1;
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * JPEG decoding is inherently inexact, so we can't test for exact
Packit 7838c8
	 * pixel values.  (Well, if we knew exactly which libjpeg version
Packit 7838c8
	 * we were using, and with what settings, we could expect specific
Packit 7838c8
	 * values ... but it's not worth the trouble to keep track of.)
Packit 7838c8
	 * Hence, use ranges of expected values.  The ranges may need to be
Packit 7838c8
	 * widened over time as more versions of libjpeg appear.
Packit 7838c8
	 */
Packit 7838c8
	pixel_status |= check_rgb_pixel( 0, 15, 18, 0, 0, 18, 41, buffer );
Packit 7838c8
	pixel_status |= check_rgb_pixel( 64, 0, 0, 0, 0, 0, 2, buffer );
Packit 7838c8
	pixel_status |= check_rgb_pixel( 512, 5, 6, 34, 36, 182, 196, buffer );
Packit 7838c8
Packit 7838c8
	free( buffer );
Packit 7838c8
Packit 7838c8
	TIFFClose(tif);
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * Reopen and test reading using the RGBA interface.
Packit 7838c8
	 */
Packit 7838c8
	tif = TIFFOpen(srcfile,"r");
Packit 7838c8
	
Packit 7838c8
	sz = 128 * 128 * sizeof(uint32);
Packit 7838c8
	rgba_buffer = (uint32 *) malloc(sz);
Packit 7838c8
	
Packit 7838c8
	if (!TIFFReadRGBATile( tif, 1*128, 2*128, rgba_buffer )) {
Packit 7838c8
		fprintf( stderr, "TIFFReadRGBATile() returned failure code.\n" );
Packit 7838c8
		return 1;
Packit 7838c8
	}
Packit 7838c8
Packit 7838c8
	/*
Packit 7838c8
	 * Currently TIFFReadRGBATile() just uses JPEGCOLORMODE_RGB so this
Packit 7838c8
	 * trivally matches the last results.  Eventually we should actually
Packit 7838c8
	 * accomplish it from the YCbCr subsampled buffer ourselves in which
Packit 7838c8
	 * case the results may be subtly different but similar.
Packit 7838c8
	 */
Packit 7838c8
	pixel_status |= check_rgba_pixel( 0, 15, 18, 0, 0, 18, 41, 255, 255,
Packit 7838c8
					  rgba_buffer );
Packit 7838c8
	pixel_status |= check_rgba_pixel( 64, 0, 0, 0, 0, 0, 2, 255, 255,
Packit 7838c8
					  rgba_buffer );
Packit 7838c8
	pixel_status |= check_rgba_pixel( 512, 5, 6, 34, 36, 182, 196, 255, 255,
Packit 7838c8
					  rgba_buffer );
Packit 7838c8
Packit 7838c8
	free( rgba_buffer );
Packit 7838c8
	TIFFClose(tif);
Packit 7838c8
Packit 7838c8
	if (pixel_status) {
Packit 7838c8
		exit(1);
Packit 7838c8
	}
Packit 7838c8
	
Packit 7838c8
	exit( 0 );
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/* vim: set ts=8 sts=8 sw=8 noet: */
Packit 7838c8
/*
Packit 7838c8
 * Local Variables:
Packit 7838c8
 * mode: c
Packit 7838c8
 * c-basic-offset: 8
Packit 7838c8
 * fill-column: 78
Packit 7838c8
 * End:
Packit 7838c8
 */