changeset 1912:4417578c55f9

improved mpo parser, consider individual image type code
author Vladimir Nadvornik <nadvornik@suse.cz>
date Sat, 09 Apr 2011 16:07:31 +0200
parents 225b72ae0482
children 3f5bd5479b48
files src/image_load_jpeg.c src/jpeg_parser.c src/jpeg_parser.h
diffstat 3 files changed, 140 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/image_load_jpeg.c	Fri Apr 08 21:16:41 2011 +0200
+++ b/src/image_load_jpeg.c	Sat Apr 09 16:07:31 2011 +0200
@@ -276,9 +276,34 @@
 	MPOData *mpo = jpeg_get_mpo_data(buf, count);
 	if (mpo && mpo->num_images > 1)
 		{
-		lj->stereo = TRUE;
-		stereo_buf2 = (unsigned char *)buf + mpo->images[1].offset;
-		stereo_length = mpo->images[1].length;
+		guint i;
+		gint idx1 = -1, idx2 = -1;
+		guint num2 = 1;
+		
+		for (i = 0; i < mpo->num_images; i++)
+			{
+			if (mpo->images[i].type_code == 0x20002)
+				{
+				if (mpo->images[i].MPIndividualNum == 1)
+					{
+					idx1 = i;
+					}
+				else if (mpo->images[i].MPIndividualNum > num2)
+					{
+					idx2 = i;
+					num2 = mpo->images[i].MPIndividualNum;
+					}
+				}
+			}
+			
+		if (idx1 >= 0 && idx2 >= 0)
+			{
+			lj->stereo = TRUE;
+			stereo_buf2 = (unsigned char *)buf + mpo->images[idx2].offset;
+			stereo_length = mpo->images[idx2].length;
+			buf = (unsigned char *)buf + mpo->images[idx1].offset;
+			count = mpo->images[idx1].length;
+			}
 		}
 	jpeg_mpo_data_free(mpo);
 
--- a/src/jpeg_parser.c	Fri Apr 08 21:16:41 2011 +0200
+++ b/src/jpeg_parser.c	Sat Apr 09 16:07:31 2011 +0200
@@ -168,7 +168,6 @@
 
 	count = tiff_byte_get_int16(tiff + offset, bo);
 	offset += 2;
-printf("count %d\n", count);
 	/* Entries and next IFD offset must be readable */
 	if (size < offset + count * TIFF_TIFD_SIZE + 4) return -1;
 
@@ -178,7 +177,6 @@
 		}
 	
 	next = tiff_byte_get_int32(tiff + offset + count * TIFF_TIFD_SIZE, bo);
-printf("next %d\n", next);
 	if (next_offset) *next_offset = next;
 	
 	return 0;
@@ -201,15 +199,17 @@
 	format = tiff_byte_get_int16(tiff + offset + TIFF_TIFD_OFFSET_FORMAT, bo);
 	count = tiff_byte_get_int32(tiff + offset + TIFF_TIFD_OFFSET_COUNT, bo);
 	data_val = tiff_byte_get_int32(tiff + offset + TIFF_TIFD_OFFSET_DATA, bo);
-printf("tag %x format %x count %x data_val %x\n", tag, format, count, data_val);
+	DEBUG_1("   tag %x format %x count %x data_val %x", tag, format, count, data_val);
 
         if (tag == 0xb000)
         	{
         	mpo->version = data_val;
+		DEBUG_1("    mpo version %x", mpo->version);
         	}
         else if (tag == 0xb001)
         	{
         	mpo->num_images = data_val;
+		DEBUG_1("    num images %x", mpo->num_images);
         	}
 	else if (tag == 0xb002)
 		{
@@ -247,13 +247,69 @@
 			 	mpo->images[i].offset += mpo->mpo_offset;
 			 	}
 			 	
-			printf("img %x %x %x\n", image_attr, mpo->images[i].length, mpo->images[i].offset);
+			DEBUG_1("   image %x %x %x", image_attr, mpo->images[i].length, mpo->images[i].offset);
 			}
 		}
 
 	return 0;
 }
 
+static gint mpo_parse_Attributes_IFD_entry(guchar *tiff, guint offset,
+				 guint size, TiffByteOrder bo,
+				 gpointer data)
+{
+	guint tag;
+	guint format;
+	guint count;
+	guint data_val;
+	guint data_offset;
+	guint data_length;
+
+	MPOEntry *mpe = data;
+
+	tag = tiff_byte_get_int16(tiff + offset + TIFF_TIFD_OFFSET_TAG, bo);
+	format = tiff_byte_get_int16(tiff + offset + TIFF_TIFD_OFFSET_FORMAT, bo);
+	count = tiff_byte_get_int32(tiff + offset + TIFF_TIFD_OFFSET_COUNT, bo);
+	data_val = tiff_byte_get_int32(tiff + offset + TIFF_TIFD_OFFSET_DATA, bo);
+	DEBUG_1("   tag %x format %x count %x data_val %x", tag, format, count, data_val);
+
+        switch (tag) 
+        	{
+        	case 0xb000: 
+        		mpe->MPFVersion = data_val;
+			DEBUG_1("    mpo version %x", data_val);
+        		break;
+        	case 0xb101: 
+        		mpe->MPIndividualNum = data_val;
+			DEBUG_1("    Individual Image Number %x", mpe->MPIndividualNum);
+        		break;
+        	case 0xb201: 
+        		mpe->PanOrientation = data_val;
+        		break;
+/*
+
+FIXME:
+Panorama Scanning Orientation PanOrientation 45569 B201 LONG 1
+Panorama Horizontal Overlap PanOverlap_H 45570 B202 RATIONAL 1
+Panorama Vertical Overlap PanOverlap_V 45571 B203 RATIONAL 1
+Base Viewpoint Number BaseViewpointNum 45572 B204 LONG 1
+Convergence Angle ConvergenceAngle 45573 B205 SRATIONAL 1
+Baseline Length BaselineLength 45574 B206 RATIONAL 1
+Divergence Angle VerticalDivergence 45575 B207 SRATIONAL 1
+Horizontal Axis Distance AxisDistance_X 45576 B208 SRATIONAL 1
+Vertical Axis Distance AxisDistance_Y 45577 B209 SRATIONAL 1
+Collimation Axis Distance AxisDistance_Z 45578 B20A SRATIONAL 1
+Yaw Angle YawAngle 45579 B20B SRATIONAL 1
+Pitch Angle PitchAngle 45580 B20C SRATIONAL 1
+Roll Angle RollAngle 45581 B20D 
+  */      	
+		default: 
+			break;
+		}
+
+	return 0;
+}
+
 MPOData *jpeg_get_mpo_data(guchar *data, guint size)
 {
 	guint seg_offset;
@@ -261,31 +317,60 @@
 	if (jpeg_segment_find(data, size, JPEG_MARKER_APP2, "MPF\x00", 4, &seg_offset, &seg_size) && seg_size >16)
 		{
 		guint offset;
+		guint next_offset;
 		TiffByteOrder bo;
 		MPOData *mpo;
 		guint i;
 
-		printf("mpo signature found at %x\n", seg_offset); 
-		data += seg_offset + 4;
+		DEBUG_1("mpo signature found at %x", seg_offset); 
+		seg_offset += 4;
 		seg_size -= 4;
 		
-		if (!tiff_directory_offset(data, seg_size, &offset, &bo)) return NULL;
+		if (!tiff_directory_offset(data + seg_offset, seg_size, &offset, &bo)) return NULL;
 
 		mpo = g_new0(MPOData, 1);
-		mpo->mpo_offset = seg_offset + 4;
+		mpo->mpo_offset = seg_offset;
 		
-		tiff_parse_IFD_table(data,  offset , seg_size, bo, NULL, mpo_parse_Index_IFD_entry, (gpointer)mpo);
+		tiff_parse_IFD_table(data + seg_offset,  offset , seg_size, bo, &next_offset, mpo_parse_Index_IFD_entry, (gpointer)mpo);
 		if (!mpo->images) mpo->num_images = 0;
 		
+	
 		for (i = 0; i < mpo->num_images; i++)
 			{
 			if (mpo->images[i].offset + mpo->images[i].length > size)
 				{
 				mpo->num_images = i;
-				DEBUG_1("MPO file truncated to %d valid images", i);
+				DEBUG_1("MPO file truncated to %d valid images, %d %d", i, mpo->images[i].offset + mpo->images[i].length, size);
 				break;
 				}
 			}
+		
+		for (i = 0; i < mpo->num_images; i++)
+			{
+			if (i == 0) 
+				{
+				offset = next_offset;
+				}
+			else
+				{
+				if (!jpeg_segment_find(data + mpo->images[i].offset, mpo->images[i].length, JPEG_MARKER_APP2, "MPF\x00", 4, &seg_offset, &seg_size) || seg_size <=16)
+					{
+					DEBUG_1("MPO image %d: MPO signature not found", i);
+					continue;
+					}
+				
+				seg_offset += 4;
+				seg_size -= 4;
+				if (!tiff_directory_offset(data + mpo->images[i].offset + seg_offset, seg_size, &offset, &bo)) 
+					{
+					DEBUG_1("MPO image %d: invalid directory offset", i);
+					continue;
+					}
+
+				}
+			tiff_parse_IFD_table(data + mpo->images[i].offset + seg_offset,  offset , seg_size, bo, NULL, mpo_parse_Attributes_IFD_entry, (gpointer)&mpo->images[i]);
+			}
+		
 		return mpo;
 		}
 	return NULL;
--- a/src/jpeg_parser.h	Fri Apr 08 21:16:41 2011 +0200
+++ b/src/jpeg_parser.h	Sat Apr 09 16:07:31 2011 +0200
@@ -48,6 +48,23 @@
 	guint length;
 	guint dep1;
 	guint dep2;
+
+	guint MPFVersion;
+	guint MPIndividualNum;  
+	guint PanOrientation;   
+	double PanOverlap_H;    
+	double PanOverlap_V;    
+	guint BaseViewpointNum; 
+	double ConvergenceAngle;
+	double BaselineLength;
+	double VerticalDivergence;
+	double AxisDistance_X;
+	double AxisDistance_Y;
+	double AxisDistance_Z;
+	double YawAngle;
+	double PitchAngle;
+	double RollAngle;
+
 };