AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
May 2005

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems



Valid HTML 4.01!



Thread

2005.05.18 15:38 "Another libtiff+libjpeg problem", by Thom Decarlo
2005.05.18 16:12 "Re: Another libtiff+libjpeg problem", by Bob Friesenhahn
2005.05.18 16:54 "Re: Another libtiff+libjpeg problem", by Thom Decarlo
2005.05.18 18:24 "Re: Another libtiff+libjpeg problem", by Thom Decarlo
2005.05.18 18:33 "Re: Another libtiff+libjpeg problem", by Bob Friesenhahn
2005.05.18 19:39 "Re: Another libtiff+libjpeg problem", by Thom Decarlo
2005.05.19 14:59 "Re: Another libtiff+libjpeg problem", by Frank Warmerdam
2005.05.19 23:00 "Re: Another libtiff+libjpeg problem", by Thom Decarlo
2005.05.20 00:00 "Re: Another libtiff+libjpeg problem", by Frank Warmerdam
2005.05.28 21:07 "Re: Another libtiff+libjpeg problem", by Thom Decarlo
2005.06.10 18:01 "Re: Another libtiff+libjpeg problem", by Frank Warmerdam
2005.06.10 18:49 "Re: Another libtiff+libjpeg problem", by Bob Friesenhahn
2005.05.25 10:12 "Re: Another libtiff+libjpeg problem", by Jean-yves Le Ridant
2005.05.25 13:31 "Re: Another libtiff+libjpeg problem", by Jean-yves Le Ridant
2005.05.26 17:57 "Re: Another libtiff+libjpeg problem", by Andrey Kiselev
2005.06.13 12:40 "Re: Another libtiff+libjpeg problem", by Jean-yves Le Ridant
2005.06.13 14:06 "Re: Another libtiff+libjpeg problem", by Andrey Kiselev
2005.06.14 10:24 "Re: Another libtiff+libjpeg problem", by Jean-yves Le Ridant
2005.06.17 08:22 "Re: Another libtiff+libjpeg problem", by Jean-yves Le Ridant
2005.06.17 16:29 "Re: Another libtiff+libjpeg problem", by Andrey Kiselev

2005.05.25 10:12 "Re: Another libtiff+libjpeg problem", by Jean-yves Le Ridant

> Sorry about that.  I believe the problem is that the CVS-head of 
> libjpeg is broken.  All my work was with the MK1-branch.  Try checking
> that out. 

As I said to Bob, I prefered restart my job for 8/12 bits
from libtiff 3.7.2 so tif_jpeg 1.30,
and the "very original ten year old v6b from IJG"
( mainly cause I could'nt .... 'think' in a jpeglib with
BITS_IN_JSAMPLE defined as cinfo.data_precision ).

I attach two diff files from tif_jpeg.c, of some job I'have done.
The first is a simple fix of some troubles
in the EncodeRaw DecodeRaw path.

The second add some support for 12/16 bits support.
It's what I use in my own stuff to have Dual (8/12/16) support
( nb: at this point, raw interface is not supported in 12/16 bits)

With the v6b, you get support for 8 or 12/16 depending the build
of jpeglib. 16 bit up/down-sampling is a simple 4 bits shift,
and that clearly ( in my mind ) reflect what it is at this point :
a convenient way to do some tests with 'blind' programs.


--
Jean-Yves

PS:
Do not hesitate if you have questions, but if not in mailing list,
allways at this 2 mails jeanyves.leridant@wanadoo.fr and
jean-yves.leridant@culture.gouv.fr

--- 372\tif_jpeg.c	2005-03-09 10:49:44.000000000 +0100
+++ mys\tif_jpeg2.c	2005-05-25 11:13:18.781250000 +0200
@@ -136,6 +136,7 @@
 	JSAMPARRAY	ds_buffer[MAX_COMPONENTS];
 	int		scancount;	/* number of "scanlines" accumulated */
 	int		samplesperclump;
+	JSAMPROW  line_work_buf;
 
 	TIFFVGetMethod	vgetparent;	/* super-class method */
 	TIFFVSetMethod	vsetparent;	/* super-class method */
@@ -144,11 +145,11 @@
 					/* pseudo-tag fields */
 	void*		jpegtables;	/* JPEGTables tag value, or NULL */
 	uint32		jpegtables_length; /* number of bytes in same */
-	int		jpegquality;	/* Compression quality level */
-	int		jpegcolormode;	/* Auto RGB<=>YCbCr convert? */
-	int		jpegtablesmode;	/* What to put in JPEGTables */
+	int			jpegquality;	/* Compression quality level */
+	int			jpegcolormode;	/* Auto RGB<=>YCbCr convert? */
+	int			jpegtablesmode;	/* What to put in JPEGTables */
 
-        int             ycbcrsampling_fetched;
+    int         ycbcrsampling_fetched;
 	uint32		recvparams;	/* encoded Class 2 session params */
 	char*		subaddress;	/* subaddress string */
 	uint32		recvtime;	/* time spent receiving (secs) */
@@ -190,6 +191,16 @@
 };
 #define	N(a)	(sizeof (a) / sizeof (a[0]))
 
+tsize_t TIFFInterleavedRowSize( JPEGState *sp, int width )
+// for 8,12,16 bps, and h_sampling at least 2, no need of howmanies  
+{
+	
+	uint16 hv_sampling = sp->h_sampling * sp->v_sampling;
+	tsize_t bpl = (width + sp->h_sampling-1)/sp->h_sampling * (hv_sampling +
2);
+	bpl *= sp->tif->tif_dir.td_bitspersample;
+	return ((tsize_t) TIFFhowmany8(bpl));
+}
+
 /*
  * libjpeg interface layer.
  *
@@ -296,10 +307,33 @@
 static int
 TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int
 num_lines)
 {
+	int bps=sp->tif->tif_dir.td_bitspersample;
+	assert(num_lines == 1);
+	if (bps==12){
+		int value_pairs = (sp->bytesperline+2)/3;
+		unsigned char *in_ptr = (unsigned char *) scanlines[0];
+		int iPair, result;
+		
+		for( iPair = 0; iPair < value_pairs; iPair++, in_ptr += 3 ){
+              JSAMPLE *out_ptr = sp->line_work_buf + iPair * 2;
+				out_ptr[0]= ( (in_ptr[0]<<4) & 0xff0 ) | ( (in_ptr[1] >> 4) & 0xf );
+				out_ptr[1]= ( in_ptr[2]&0xff )  | ( (in_ptr[1]<<8) & 0xf00 )  ;
+		}
+		result= CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c,
&sp->line_work_buf, (JDIMENSION) num_lines));
+		return result;
+	}
+	if ( bps == 16){
+		int count = sp->bytesperline/2;
+		uint16 *row = (uint16 *) scanlines[0];
+		while ( count-- ) { *row >>= 4 ; row++; }
+	}
 	return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c,
 	    scanlines, (JDIMENSION) num_lines));
 }
 
+
+
+
 static int
 TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines)
 {
@@ -334,8 +368,36 @@
 static int
 TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines)
 {
-	return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d,
-	    scanlines, (JDIMENSION) max_lines));
+	int bps = sp->tif->tif_dir.td_bitspersample;
+	assert(max_lines==1);
+	if(bps != 12) {
+		int result= CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d,
scanlines, (JDIMENSION) max_lines));
+		if (!result || bps==8) 
+			return result;
+		{	/* process a 16 bits line */
+			int count= sp->bytesperline/2;
+			uint16 * row = (uint16 *) scanlines[0];
+			while ( count-- ) { *row <<= 4 ; row++; }
+			return 1;
+		}
+	}
+	{	/* process 12 bits line */
+		int result;
+		result= CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d,
&sp->line_work_buf, (JDIMENSION) max_lines));
+		if (result) {
+			unsigned char *out_ptr = (unsigned char *) scanlines[0];
+			JSAMPLE *in_ptr = sp->line_work_buf;
+			int out_count;
+			 for( out_count=sp->bytesperline ; out_count> 0 ; out_count--, out_ptr
+= 3, in_ptr += 2 )
+             {
+                 out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
+                 out_ptr[1] = ((in_ptr[0] & 0xf) << 4) | ((in_ptr[1] &
0xf00) >> 8);
+				 out_count-=2;
+				 if (out_count) out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
+             } 
+		}
+		return result;
+	}
 }
 
 static int
@@ -615,6 +677,15 @@
 	return (1);
 }
 
+static int alloc_linework12_buffer(JPEGState* sp )
+{
+	int countpairs= (sp->bytesperline+2)/3;
+	JSAMPARRAY buf= TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE, countpairs * 2, 1);
+	if(buf==NULL) return 0;
+	sp->line_work_buf=buf[0];
+	return 1;
+}
+
 
 /*
  * JPEG Decoding.
@@ -723,7 +794,7 @@
 		TIFFError(module, "Improper JPEG component count");
 		return (0);
 	}
-	if (sp->cinfo.d.data_precision != td->td_bitspersample) {
+	if ( (sp->cinfo.d.data_precision != td->td_bitspersample) && !
(td->td_bitspersample==16 && BITS_IN_JSAMPLE==12 ) ) {
 		TIFFError(module, "Improper JPEG data precision");
 		return (0);
 	}
@@ -792,6 +863,10 @@
 	}
 	if (downsampled_output) {
 		/* Need to use raw-data interface to libjpeg */
+		if(sp->cinfo.d.data_precision == 12){
+			TIFFError(module, "Raw mode not supported only for 8 bits mode");
+			return 0;
+		}
 		sp->cinfo.d.raw_data_out = TRUE;
 		tif->tif_decoderow = JPEGDecodeRaw;
 		tif->tif_decodestrip = JPEGDecodeRaw;
@@ -808,11 +883,14 @@
 		return (0);
 	/* Allocate downsampled-data buffers if needed */
 	if (downsampled_output) {
+		sp->bytesperline= TIFFInterleavedRowSize(sp, segment_width);
 		if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info,
 					       sp->cinfo.d.num_components))
 			return (0);
 		sp->scancount = DCTSIZE;	/* mark buffer empty */
 	}
+	if( tif->tif_dir.td_bitspersample == 12 && ! alloc_linework12_buffer(sp) )
+		return 0;
 	return (1);
 }
 
@@ -859,15 +937,16 @@
 JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
 {
 	JPEGState *sp = JState(tif);
-	tsize_t nrows;
+	JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;
+	int samples_per_clump = sp->samplesperclump;
+	tsize_t nrows= cc / sp->bytesperline;
 
 	/* data is expected to be read in multiples of a scanline */
-	if ( (nrows = sp->cinfo.d.image_height) ) {
-		/* Cb,Cr both have sampling factors 1, so this is correct */
-		JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;
-		int samples_per_clump = sp->samplesperclump;
-	
-		do {
+
+	if (cc % sp->bytesperline)
+		TIFFWarning(tif->tif_name, "fractional scanline discarded");
+
+	while( nrows-- ) {
 			jpeg_component_info *compptr;
 			int ci, clumpoffset;
 
@@ -917,10 +996,9 @@
 			    }
 			}
 			++sp->scancount;
-			++tif->tif_row;
+			tif->tif_row += sp->v_sampling;
 			buf += sp->bytesperline;
 			cc -= sp->bytesperline;
-		} while (--nrows > 0);
 	}
 
         /* Close down the decompressor if done. */
@@ -1051,12 +1129,17 @@
 	 * depths for different components, or if libjpeg ever supports
 	 * run-time selection of depth.  Neither is imminent.
 	 */
-	if (td->td_bitspersample != BITS_IN_JSAMPLE) {
-		TIFFError(module, "BitsPerSample %d not allowed for JPEG",
-			  (int) td->td_bitspersample);
-		return (0);
+	if (td->td_bitspersample != BITS_IN_JSAMPLE ){
+		if ( ! (td->td_bitspersample==16 && BITS_IN_JSAMPLE==12 ) ) {
+				TIFFError(module, "BitsPerSample %d not allowed for JPEG",
+						(int) td->td_bitspersample);
+				return (0);
+		}
+		else 
+			sp->cinfo.c.data_precision = 12;
 	}
-	sp->cinfo.c.data_precision = td->td_bitspersample;
+	else 
+		sp->cinfo.c.data_precision = td->td_bitspersample;
 	if (isTiled(tif)) {
 		if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) {
 			TIFFError(module,
@@ -1189,12 +1272,19 @@
 		unsuppress_quant_table(sp, 0);
 		unsuppress_quant_table(sp, 1);
 	}
+	//if( BITS_IN_JSAMPLE == 12) sp->jpegtablesmode &= ( JPEGTABLESMODE_HUFF ^
0xFFFF ); 
+	sp->jpegtablesmode &= ( JPEGTABLESMODE_HUFF ^ 0xFFFF ); 
+	/* for 8 bits also ---> anticipating some "low-speed" complains in 12 bits
mode ;-))) */
 	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
 		sp->cinfo.c.optimize_coding = FALSE;
-	else
+	else 
 		sp->cinfo.c.optimize_coding = TRUE;
 	if (downsampled_input) {
 		/* Need to use raw-data interface to libjpeg */
+		if(sp->cinfo.c.data_precision == 12){
+			TIFFError(module, "Raw mode not supported only for 8 bits mode");
+			return 0;
+		}
 		sp->cinfo.c.raw_data_in = TRUE;
 		tif->tif_encoderow = JPEGEncodeRaw;
 		tif->tif_encodestrip = JPEGEncodeRaw;
@@ -1211,12 +1301,14 @@
 		return (0);
 	/* Allocate downsampled-data buffers if needed */
 	if (downsampled_input) {
+		sp->bytesperline= TIFFInterleavedRowSize(sp, segment_width);
 		if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info,
 					       sp->cinfo.c.num_components))
 			return (0);
 	}
 	sp->scancount = 0;
-
+	if( tif->tif_dir.td_bitspersample == 12 && ! alloc_linework12_buffer(sp) )
+		return 0;
 	return (1);
 }
 
@@ -1320,8 +1412,7 @@
 				return (0);
 			sp->scancount = 0;
 		}
-		if (nrows > 0)
-			tif->tif_row++;
+		tif->tif_row += sp->v_sampling;
 		buf += sp->bytesperline;
 	}
 	return (1);


--- 372\tif_jpeg.c	2005-03-09 10:49:44.000000000 +0100
+++ mys\tif_jpeg1.c	2005-05-20 14:39:48.500000000 +0200
@@ -190,6 +190,16 @@
 };
 #define	N(a)	(sizeof (a) / sizeof (a[0]))
 
+tsize_t TIFFInterleavedRowSize( JPEGState *sp, int width )
+// for 8,12,16 bps, and h_sampling at least 2, no need of howmanies  
+{
+	
+	uint16 hv_sampling = sp->h_sampling * sp->v_sampling;
+	tsize_t bpl = (width + sp->h_sampling-1)/sp->h_sampling * (hv_sampling + 2);
+	bpl *= sp->tif->tif_dir.td_bitspersample;
+	return ((tsize_t) TIFFhowmany8(bpl));
+}
+
 /*
  * libjpeg interface layer.
  *
@@ -808,6 +818,7 @@
 		return (0);
 	/* Allocate downsampled-data buffers if needed */
 	if (downsampled_output) {
+		sp->bytesperline= TIFFInterleavedRowSize(sp, segment_width);
 		if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info,
 					       sp->cinfo.d.num_components))
 			return (0);
@@ -859,15 +870,16 @@
 JPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
 {
 	JPEGState *sp = JState(tif);
-	tsize_t nrows;
+	JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;
+	int samples_per_clump = sp->samplesperclump;
+	tsize_t nrows= cc / sp->bytesperline;
 
 	/* data is expected to be read in multiples of a scanline */
-	if ( (nrows = sp->cinfo.d.image_height) ) {
-		/* Cb,Cr both have sampling factors 1, so this is correct */
-		JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;
-		int samples_per_clump = sp->samplesperclump;
-	
-		do {
+
+	if (cc % sp->bytesperline)
+		TIFFWarning(tif->tif_name, "fractional scanline discarded");
+
+	while( nrows-- ) {
 			jpeg_component_info *compptr;
 			int ci, clumpoffset;
 
@@ -917,10 +929,9 @@
 			    }
 			}
 			++sp->scancount;
-			++tif->tif_row;
+			tif->tif_row += sp->v_sampling;
 			buf += sp->bytesperline;
 			cc -= sp->bytesperline;
-		} while (--nrows > 0);
 	}
 
         /* Close down the decompressor if done. */
@@ -1211,6 +1222,7 @@
 		return (0);
 	/* Allocate downsampled-data buffers if needed */
 	if (downsampled_input) {
+		sp->bytesperline= TIFFInterleavedRowSize(sp, segment_width);
 		if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info,
 					       sp->cinfo.c.num_components))
 			return (0);
@@ -1320,8 +1332,7 @@
 				return (0);
 			sp->scancount = 0;
 		}
-		if (nrows > 0)
-			tif->tif_row++;
+		tif->tif_row += sp->v_sampling;
 		buf += sp->bytesperline;
 	}
 	return (1);