Index: libgthumb/gth-exif-utils.c
===================================================================
--- libgthumb/gth-exif-utils.c	(revision 1582)
+++ libgthumb/gth-exif-utils.c	(working copy)
@@ -668,15 +668,16 @@
  
 #define IFD_NAME_PUSH(val) names[ni++] = val;
 #define IFD_NAME_PULL()    names[--ni]
- 
-int
-gth_minimal_exif_tag_write (const char *filename,
- 	                    ExifTag     etag,
- 			    void       *data,
- 			    int         size,
- 			    int         ifds)
+
+int static
+gth_minimal_exif_tag_action (const char *filename,
+			     ExifTag     etag,
+			     void       *data,
+			     int         size,
+			     int         ifds,
+			     int         access)
 {
-	/* This function updates ONLY the affected tag. Unlike libexif, it does
+	/* This function updates/reads ONLY the affected tag. Unlike libexif, it does
 	   not attempt to correct or re-format other data. This helps preserve
 	   the integrity of certain MakerNote entries, by avoiding re-positioning
 	   of the data whenever possible. Some MakerNotes incorporate absolute
@@ -707,7 +708,7 @@
         int           ni = 0;       // iundex into names
  	int           cifdi = 0;    // curret ifd index
  
- 	debug (DEBUG_INFO, "gth_minimal_exif_tag_write(%s, %04x, %08x, %d, %02x)\n", filename, etag, data, size, ifds);
+ 	debug (DEBUG_INFO, "gth_minimal_exif_tag_access(%s, %04x, %08x, %d, %02x)\n", filename, etag, data, size, ifds);
  
         // Init IFD stack
  	IFD_OFFSET_PUSH(0);
@@ -790,53 +791,99 @@
  			// Our tag?
  			if (bcmp(&buf[i], (char *)&tag, 2) == 0){ 
  
- 				debug (DEBUG_INFO, "*");
+				// Write TAG value
+				if (access == 1){ 
 
- 				// Local value that can be patched directly in TAG table 
- 				if ((types[type] * count) <= 4){
+					// Local value that can be patched directly in TAG table 
+					if ((types[type] * count) <= 4){
  
- 					// Fake TIFF offset
- 					offset = i + 8 - tiff; 
- 					patches++;
- 				}
- 				// Offseted value of same or larger size that we can patch
- 				else if (types[type] * count >= size){
+						// Fake TIFF offset
+						offset = i + 8 - tiff; 
+						patches++;
+					}
+					// Offseted value of same or larger size that we can patch
+					else if (types[type] * count >= size){
+						
+						// Adjust count to new length
+						count = size / types[type]; 
+						*((unsigned short*)(&buf[i + 4])) = ENDIAN32_IT(count);
+						patches++;
+					}
+					// Otherwise we are not able to patch the new value, at least not here
+					else {
+						fprintf(stderr, "gth_minimal_exif_tag_write: New TAG value does not fit, no patch applied\n");
+						continue;
+					}
+					
+					if (offset + tiff + count * types[type] > sizeof(buf)) return PATCH_EXIF_TRASHED_IFD;
+
+					// Copy the data
+					stitch = 0;
+					while (stitch < count){
+						switch (types[type]){
+						case 1:
+							buf[tiff + offset + stitch] = *(char *) (data + stitch);
+							break;
+						case 2:
+							*((unsigned short*)(&buf[tiff + offset + stitch * 2])) = 
+								ENDIAN16_IT(*(guint16 *) (data + stitch * 2));
+							break;
+						case 4:
+							*((unsigned long*) (&buf[tiff + offset + stitch * 4])) = 
+								ENDIAN32_IT(*(guint32 *) (data + stitch * 4));
+							break;
+						default:
+							fprintf(stderr, "gth_minimal_exif_tag_write:unsupported element size\n");
+							return PATCH_EXIF_UNSUPPORTED_TYPE;
+						}
+						stitch++;
+					}
+				}
+				// Read a TAG value
+				else{ 
+
+					// Local value that can be read directly in TAG table 
+					if ((types[type] * count) <= 4 && size >= (types[type] * count)){
  
- 					// Adjust count to new length
- 					count = size / types[type]; 
- 					*((unsigned short*)(&buf[i + 4])) = ENDIAN32_IT(count);
- 					patches++;
- 				}
- 				// Otherwise we are not able to patch the new value, at least not here
- 				else {
- 					fprintf(stderr, "gth_minimal_exif_tag_write: New TAG value does not fit, no patch applied\n");
- 					continue;
- 				}
-				
-				if (offset + tiff + count * types[type] > sizeof(buf)) return PATCH_EXIF_TRASHED_IFD;
-
- 				// Copy the data
- 				stitch = 0;			       
- 				while (stitch < count){
- 					switch (types[type]){
- 					case 1:
- 						buf[tiff + offset + stitch] = *(char *) (data + stitch);
- 						break;
- 					case 2:
- 						*((unsigned short*)(&buf[tiff + offset + stitch * 2])) = 
- 							ENDIAN16_IT(*(guint16 *) (data + stitch * 2));
- 						break;
- 					case 4:
- 						*((unsigned long*) (&buf[tiff + offset + stitch * 4])) = 
- 							ENDIAN32_IT(*(guint32 *) (data + stitch * 4));
- 						break;
- 					default:
- 						fprintf(stderr, "gth_minimal_exif_tag_write:unsupported element size\n");
-						return PATCH_EXIF_UNSUPPORTED_TYPE;
- 					}
- 					stitch++;
- 				}
- 			}
+						// Fake TIFF offset
+						offset = i + 8 - tiff; 
+						patches++;
+					}
+					// Offseted value of less or equal size than buffer
+					else if (types[type] * count <= size){
+						patches++;
+					}
+					// Otherwise we are not able to read the value
+					else {
+						fprintf(stderr, "gth_minimal_exif_tag_read: TAG value does not fit, Can't read value\n");
+						continue;
+					}
+					
+					stitch = 0;
+					while (stitch < count){
+						switch (types[type]){
+						case 1:
+							*(char *) (data + stitch) = buf[tiff + offset + stitch];
+							break;
+						case 2:
+							*(guint16 *) (data + stitch * 2) = 
+								DE_ENDIAN16(*((unsigned short*)(&buf[tiff + offset + stitch * 2])));
+							
+							break;
+						case 4:
+							*(guint32 *) (data + stitch * 4) =
+								DE_ENDIAN32(*((unsigned long*) (&buf[tiff + offset + stitch * 4])));
+							
+							break;
+						default:
+							fprintf(stderr, "gth_minimal_exif_tag_read:unsupported element size\n");
+							return PATCH_EXIF_UNSUPPORTED_TYPE;
+						}
+						stitch++;
+					}					
+					return PATCH_EXIF_OK;
+				}
+			}
  			// EXIF pointer tag?
  			else if (bcmp(&buf[i], (char *)&exififd, 2) == 0){ 
  				IFD_OFFSET_PUSH(offset + tiff);
@@ -877,6 +924,28 @@
 }
 
 
+int
+gth_minimal_exif_tag_read (const char *filename,
+ 	                    ExifTag     etag,
+ 			    void       *data,
+ 			    int         size,
+ 			    int         ifds)
+{
+ 	debug (DEBUG_INFO, "gth_minimal_exif_tag_read(%s, %04x, %08x, %d, %02x)\n", filename, etag, data, size, ifds); 
+	return gth_minimal_exif_tag_action(filename, etag, data, size, ifds, 0);
+}
+
+int
+gth_minimal_exif_tag_write (const char *filename,
+ 	                    ExifTag     etag,
+ 			    void       *data,
+ 			    int         size,
+ 			    int         ifds)
+{
+ 	debug (DEBUG_INFO, "gth_minimal_exif_tag_write(%s, %04x, %08x, %d, %02x)\n", filename, etag, data, size, ifds); 
+	return gth_minimal_exif_tag_action(filename, etag, data, size, ifds, 1);
+}
+
 GthTransform
 read_orientation_field (const char *path)
 {
Index: libgthumb/gth-exif-utils.h
===================================================================
--- libgthumb/gth-exif-utils.h	(revision 1582)
+++ libgthumb/gth-exif-utils.h	(working copy)
@@ -66,6 +66,11 @@
                                            void         *data,
                                            int           size,
                                            int           ifds);
+int           gth_minimal_exif_tag_read  (const char   *filename,
+                                           ExifTag       etag,
+                                           void         *data,
+                                           int           size,
+                                           int           ifds);
 GthTransform  read_orientation_field      (const char   *path);
 void	      write_orientation_field     (const char   *filename, 
 				  	   GthTransform  transform);
