kusano 7d535a
/* $Id: raw_decode.c,v 1.4 2012-07-06 17:05:16 bfriesen Exp $ */
kusano 7d535a
kusano 7d535a
/*
kusano 7d535a
 * Copyright (c) 2012, Frank Warmerdam <warmerdam@pobox.com></warmerdam@pobox.com>
kusano 7d535a
 *
kusano 7d535a
 * Permission to use, copy, modify, distribute, and sell this software and 
kusano 7d535a
 * its documentation for any purpose is hereby granted without fee, provided
kusano 7d535a
 * that (i) the above copyright notices and this permission notice appear in
kusano 7d535a
 * all copies of the software and related documentation, and (ii) the names of
kusano 7d535a
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
kusano 7d535a
 * publicity relating to the software without the specific, prior written
kusano 7d535a
 * permission of Sam Leffler and Silicon Graphics.
kusano 7d535a
 * 
kusano 7d535a
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
kusano 7d535a
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
kusano 7d535a
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
kusano 7d535a
 * 
kusano 7d535a
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
kusano 7d535a
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
kusano 7d535a
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
kusano 7d535a
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
kusano 7d535a
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
kusano 7d535a
 * OF THIS SOFTWARE.
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
/*
kusano 7d535a
 * TIFF Library
kusano 7d535a
 *
kusano 7d535a
 * The objective of this test suite is to test the JPEGRawDecode() 
kusano 7d535a
 * interface via TIFReadEncodedTile().  This function with YCbCr subsampling
kusano 7d535a
 * is a frequent source of bugs. 
kusano 7d535a
 */
kusano 7d535a
kusano 7d535a
#include "tif_config.h"
kusano 7d535a
kusano 7d535a
#include <stdio.h></stdio.h>
kusano 7d535a
#include <stdlib.h></stdlib.h>
kusano 7d535a
#include <string.h></string.h>
kusano 7d535a
#ifdef HAVE_UNISTD_H 
kusano 7d535a
# include <unistd.h> </unistd.h>
kusano 7d535a
#endif 
kusano 7d535a
kusano 7d535a
#include "tiffio.h"
kusano 7d535a
kusano 7d535a
#include "jpeglib.h" /* Needed for JPEG_LIB_VERSION */
kusano 7d535a
kusano 7d535a
static unsigned char cluster_0[] = { 0, 0, 2, 0, 138, 139 };
kusano 7d535a
static unsigned char cluster_64[] = { 0, 0, 9, 6, 134, 119 };
kusano 7d535a
static unsigned char cluster_128[] = { 44, 40, 63, 59, 230, 95 };
kusano 7d535a
kusano 7d535a
static int check_cluster( int cluster, unsigned char *buffer, unsigned char *expected_cluster ) {
kusano 7d535a
	unsigned char *target = buffer + cluster*6;
kusano 7d535a
kusano 7d535a
	if (memcmp(target, expected_cluster, 6) == 0) {
kusano 7d535a
		return 0;
kusano 7d535a
	}
kusano 7d535a
kusano 7d535a
	fprintf( stderr, "Cluster %d did not match expected results.\n", cluster );
kusano 7d535a
	fprintf( stderr, 
kusano 7d535a
		 "Expect: %3d %3d   %3d   %3d\n"
kusano 7d535a
		 "        %3d %3d\n", 
kusano 7d535a
		 expected_cluster[0], expected_cluster[1],
kusano 7d535a
		 expected_cluster[4], expected_cluster[5],
kusano 7d535a
		 expected_cluster[2], expected_cluster[3] );
kusano 7d535a
	fprintf( stderr, 
kusano 7d535a
		 "   Got: %3d %3d   %3d   %3d\n"
kusano 7d535a
		 "        %3d %3d\n", 
kusano 7d535a
		 target[0], target[1], 
kusano 7d535a
		 target[4], target[5],
kusano 7d535a
		 target[2], target[3] );
kusano 7d535a
	return 1;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
static int check_rgb_pixel( int pixel, int red, int green, int blue, unsigned char *buffer ) {
kusano 7d535a
	unsigned char *rgb = buffer + 3 * pixel;
kusano 7d535a
	
kusano 7d535a
	if( rgb[0] == red && rgb[1] == green && rgb[2] == blue ) {
kusano 7d535a
		return 0;
kusano 7d535a
	}
kusano 7d535a
kusano 7d535a
	fprintf( stderr, "Pixel %d did not match expected results.\n", pixel );
kusano 7d535a
	fprintf( stderr, "Expect: %3d %3d %3d\n", red, green, blue );
kusano 7d535a
	fprintf( stderr, "   Got: %3d %3d %3d\n", rgb[0], rgb[1], rgb[2] );
kusano 7d535a
	return 1;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
static int check_rgba_pixel( int pixel, int red, int green, int blue, int alpha, uint32 *buffer ) {
kusano 7d535a
	/* RGBA images are upside down - adjust for normal ordering */
kusano 7d535a
	int adjusted_pixel = pixel % 128 + (127 - (pixel/128)) * 128;
kusano 7d535a
	uint32 rgba = buffer[adjusted_pixel];
kusano 7d535a
kusano 7d535a
	if( TIFFGetR(rgba) == (uint32) red && TIFFGetG(rgba) == (uint32) green &&
kusano 7d535a
	    TIFFGetB(rgba) == (uint32) blue && TIFFGetA(rgba) == (uint32) alpha ) {
kusano 7d535a
		return 0;
kusano 7d535a
	}
kusano 7d535a
kusano 7d535a
	fprintf( stderr, "Pixel %d did not match expected results.\n", pixel );
kusano 7d535a
	fprintf( stderr, "Expect: %3d %3d %3d %3d\n", red, green, blue, alpha );
kusano 7d535a
	fprintf( stderr, "   Got: %3d %3d %3d %3d\n",
kusano 7d535a
		 TIFFGetR(rgba), TIFFGetG(rgba), TIFFGetB(rgba), TIFFGetA(rgba) );
kusano 7d535a
	return 1;
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
int
kusano 7d535a
main(int argc, char **argv)
kusano 7d535a
{
kusano 7d535a
	TIFF		*tif;
kusano 7d535a
	static const char *srcfilerel = "images/quad-tile.jpg.tiff";
kusano 7d535a
	char *srcdir = NULL;
kusano 7d535a
	char srcfile[1024];
kusano 7d535a
	unsigned short h, v;
kusano 7d535a
	int status;
kusano 7d535a
	unsigned char *buffer;
kusano 7d535a
	uint32 *rgba_buffer;
kusano 7d535a
	tsize_t sz, szout;
kusano 7d535a
	unsigned int pixel_status = 0;
kusano 7d535a
kusano 7d535a
        (void) argc;
kusano 7d535a
        (void) argv;
kusano 7d535a
kusano 7d535a
	if ((srcdir = getenv("srcdir")) == NULL) {
kusano 7d535a
		srcdir = ".";
kusano 7d535a
	}
kusano 7d535a
	if ((strlen(srcdir) + 1 + strlen(srcfilerel)) >= sizeof(srcfile)) {
kusano 7d535a
		fprintf( stderr, "srcdir too long %s\n", srcdir);
kusano 7d535a
		exit( 1 );
kusano 7d535a
	}
kusano 7d535a
	strcpy(srcfile,srcdir);
kusano 7d535a
	strcat(srcfile,"/");
kusano 7d535a
	strcat(srcfile,srcfilerel);
kusano 7d535a
kusano 7d535a
	tif = TIFFOpen(srcfile,"r");
kusano 7d535a
	if ( tif == NULL ) {
kusano 7d535a
		fprintf( stderr, "Could not open %s\n", srcfile);
kusano 7d535a
		exit( 1 );
kusano 7d535a
	}
kusano 7d535a
kusano 7d535a
	status = TIFFGetField(tif,TIFFTAG_YCBCRSUBSAMPLING, &h, &v);
kusano 7d535a
	if ( status == 0 || h != 2 || v != 2) {
kusano 7d535a
		fprintf( stderr, "Could not retrieve subsampling tag.\n" );
kusano 7d535a
		exit(1);
kusano 7d535a
	}
kusano 7d535a
kusano 7d535a
	/*
kusano 7d535a
	 * What is the appropriate size of a YCbCr encoded tile?
kusano 7d535a
	 */
kusano 7d535a
	sz = TIFFTileSize(tif);
kusano 7d535a
	if( sz != 24576) {
kusano 7d535a
		fprintf(stderr, "tiles are %d bytes\n", (int)sz);
kusano 7d535a
		exit(1);
kusano 7d535a
	}
kusano 7d535a
kusano 7d535a
	buffer = (unsigned char *) malloc(sz);
kusano 7d535a
kusano 7d535a
	/*
kusano 7d535a
	 * Read a tile in decompressed form, but still YCbCr subsampled.
kusano 7d535a
	 */
kusano 7d535a
	szout = TIFFReadEncodedTile(tif,9,buffer,sz);
kusano 7d535a
	if (szout != sz) {
kusano 7d535a
		fprintf( stderr, 
kusano 7d535a
			 "Did not get expected result code from TIFFReadEncodedTile()(%d instead of %d)\n", 
kusano 7d535a
			 (int) szout, (int) sz );
kusano 7d535a
		return 1;
kusano 7d535a
	}
kusano 7d535a
kusano 7d535a
	if( check_cluster( 0, buffer, cluster_0 )
kusano 7d535a
	    || check_cluster( 64, buffer, cluster_64 )
kusano 7d535a
	    || check_cluster( 128, buffer, cluster_128 ) ) {
kusano 7d535a
		exit(1);
kusano 7d535a
	}
kusano 7d535a
	free(buffer);
kusano 7d535a
kusano 7d535a
	/*
kusano 7d535a
	 * Read a tile using the built-in conversion to RGB format provided by the JPEG library.
kusano 7d535a
	 */
kusano 7d535a
	TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
kusano 7d535a
kusano 7d535a
	sz = TIFFTileSize(tif);
kusano 7d535a
	if( sz != 128*128*3) {
kusano 7d535a
		fprintf(stderr, "tiles are %d bytes\n", (int)sz);
kusano 7d535a
		exit(1);
kusano 7d535a
	}
kusano 7d535a
kusano 7d535a
	buffer = (unsigned char *) malloc(sz);
kusano 7d535a
kusano 7d535a
	szout = TIFFReadEncodedTile(tif,9,buffer,sz);
kusano 7d535a
	if (szout != sz) {
kusano 7d535a
		fprintf( stderr, 
kusano 7d535a
			 "Did not get expected result code from TIFFReadEncodedTile()(%d instead of %d)\n", 
kusano 7d535a
			 (int) szout, (int) sz );
kusano 7d535a
		return 1;
kusano 7d535a
	}
kusano 7d535a
kusano 7d535a
#if JPEG_LIB_VERSION >= 70
kusano 7d535a
	pixel_status |= check_rgb_pixel( 0, 18, 0, 41, buffer );
kusano 7d535a
	pixel_status |= check_rgb_pixel( 64, 0, 0, 0, buffer );
kusano 7d535a
	pixel_status |= check_rgb_pixel( 512, 5, 34, 196, buffer );
kusano 7d535a
#else
kusano 7d535a
	pixel_status |= check_rgb_pixel( 0, 15, 0, 18, buffer );
kusano 7d535a
	pixel_status |= check_rgb_pixel( 64, 0, 0, 2, buffer );
kusano 7d535a
	pixel_status |= check_rgb_pixel( 512, 6, 36, 182, buffer );
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
	free( buffer );
kusano 7d535a
kusano 7d535a
	TIFFClose(tif);
kusano 7d535a
kusano 7d535a
	/*
kusano 7d535a
	 * Reopen and test reading using the RGBA interface.
kusano 7d535a
	 */
kusano 7d535a
	tif = TIFFOpen(srcfile,"r");
kusano 7d535a
	
kusano 7d535a
	sz = 128 * 128 * sizeof(uint32);
kusano 7d535a
	rgba_buffer = (uint32 *) malloc(sz);
kusano 7d535a
	
kusano 7d535a
	if (!TIFFReadRGBATile( tif, 1*128, 2*128, rgba_buffer )) {
kusano 7d535a
		fprintf( stderr, "TIFFReadRGBATile() returned failure code.\n" );
kusano 7d535a
		return 1;
kusano 7d535a
	}
kusano 7d535a
kusano 7d535a
	/*
kusano 7d535a
	 * Currently TIFFReadRGBATile() just uses JPEGCOLORMODE_RGB so this
kusano 7d535a
	 * trivally matches the last results.  Eventually we should actually
kusano 7d535a
	 * accomplish it from the YCbCr subsampled buffer ourselves in which
kusano 7d535a
	 * case the results may be subtly different but similar.
kusano 7d535a
	 */
kusano 7d535a
#if JPEG_LIB_VERSION >= 70
kusano 7d535a
	pixel_status |= check_rgba_pixel( 0, 18, 0, 41, 255, rgba_buffer );
kusano 7d535a
	pixel_status |= check_rgba_pixel( 64, 0, 0, 0, 255, rgba_buffer );
kusano 7d535a
	pixel_status |= check_rgba_pixel( 512, 5, 34, 196, 255, rgba_buffer );
kusano 7d535a
#else
kusano 7d535a
	pixel_status |= check_rgba_pixel( 0, 15, 0, 18, 255, rgba_buffer );
kusano 7d535a
	pixel_status |= check_rgba_pixel( 64, 0, 0, 2, 255, rgba_buffer );
kusano 7d535a
	pixel_status |= check_rgba_pixel( 512, 6, 36, 182, 255, rgba_buffer );
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
	free( rgba_buffer );
kusano 7d535a
	TIFFClose(tif);
kusano 7d535a
kusano 7d535a
	if (pixel_status) {
kusano 7d535a
		exit(1);
kusano 7d535a
	}
kusano 7d535a
	
kusano 7d535a
	exit( 0 );
kusano 7d535a
}
kusano 7d535a
kusano 7d535a
/* vim: set ts=8 sts=8 sw=8 noet: */
kusano 7d535a
/*
kusano 7d535a
 * Local Variables:
kusano 7d535a
 * mode: c
kusano 7d535a
 * c-basic-offset: 8
kusano 7d535a
 * fill-column: 78
kusano 7d535a
 * End:
kusano 7d535a
 */