=== id3tag.h
==================================================================
--- id3tag.h	(revision 53928)
+++ id3tag.h	(local)
@@ -247,7 +247,8 @@
 
 enum id3_file_mode {
   ID3_FILE_MODE_READONLY = 0,
-  ID3_FILE_MODE_READWRITE
+  ID3_FILE_MODE_READWRITE,
+  ID3_FILE_MODE_READONLY_NOSEEK
 };
 
 struct id3_file *id3_file_open(char const *, enum id3_file_mode);
=== file.c
==================================================================
--- file.c	(revision 53928)
+++ file.c	(local)
@@ -265,40 +265,42 @@
 {
   fpos_t save_position;
   signed long size;
+  
+  if ( !(file->mode & ID3_FILE_MODE_READONLY_NOSEEK) ) {
 
-  /*
-   * save the current seek position
-   *
-   * We also verify the stream is seekable by calling fsetpos(), since
-   * fgetpos() alone is not reliable enough for this purpose.
-   *
-   * [Apparently not even fsetpos() is sufficient under Win32.]
-   */
+    /*
+     * save the current seek position
+     *
+     * We also verify the stream is seekable by calling fsetpos(), since
+     * fgetpos() alone is not reliable enough for this purpose.
+     *
+     * [Apparently not even fsetpos() is sufficient under Win32.]
+     */
 
-  if (fgetpos(file->iofile, &save_position) == -1 ||
-      fsetpos(file->iofile, &save_position) == -1)
-    return -1;
+    if (fgetpos(file->iofile, &save_position) == -1 ||
+        fsetpos(file->iofile, &save_position) == -1)
+      return -1;
 
-  /* look for an ID3v1 tag */
+    /* look for an ID3v1 tag */
 
-  if (fseek(file->iofile, -128, SEEK_END) == 0) {
-    size = query_tag(file->iofile);
-    if (size > 0) {
-      struct id3_tag const *tag;
+    if (fseek(file->iofile, -128, SEEK_END) == 0) {
+      size = query_tag(file->iofile);
+      if (size > 0) {
+        struct id3_tag const *tag;
 
-      tag = add_tag(file, size);
+        tag = add_tag(file, size);
 
-      /* if this is indeed an ID3v1 tag, mark the file so */
+        /* if this is indeed an ID3v1 tag, mark the file so */
 
-      if (tag && (ID3_TAG_VERSION_MAJOR(id3_tag_version(tag)) == 1))
-	file->flags |= ID3_FILE_FLAG_ID3V1;
+        if (tag && (ID3_TAG_VERSION_MAJOR(id3_tag_version(tag)) == 1))
+  	file->flags |= ID3_FILE_FLAG_ID3V1;
+      }
     }
+
+    /* look for a tag at the beginning of the file */
+    rewind(file->iofile);
   }
 
-  /* look for a tag at the beginning of the file */
-
-  rewind(file->iofile);
-
   size = query_tag(file->iofile);
   if (size > 0) {
     struct id3_tag const *tag;
@@ -319,25 +321,27 @@
       tag  = (size > 0) ? add_tag(file, size) : 0;
     }
   }
+  
+  if ( !(file->mode & ID3_FILE_MODE_READONLY_NOSEEK) ) {
+    /* look for a tag at the end of the file (before any ID3v1 tag) */
 
-  /* look for a tag at the end of the file (before any ID3v1 tag) */
-
-  if (fseek(file->iofile, ((file->flags & ID3_FILE_FLAG_ID3V1) ? -128 : 0) +
-	    -10, SEEK_END) == 0) {
-    size = query_tag(file->iofile);
-    if (size < 0 && fseek(file->iofile, size, SEEK_CUR) == 0) {
+    if (fseek(file->iofile, ((file->flags & ID3_FILE_FLAG_ID3V1) ? -128 : 0) +
+  	    -10, SEEK_END) == 0) {
       size = query_tag(file->iofile);
-      if (size > 0)
-	add_tag(file, size);
+      if (size < 0 && fseek(file->iofile, size, SEEK_CUR) == 0) {
+        size = query_tag(file->iofile);
+        if (size > 0)
+  	add_tag(file, size);
+      }
     }
-  }
 
-  clearerr(file->iofile);
+    clearerr(file->iofile);
 
-  /* restore seek position */
+    /* restore seek position */
 
-  if (fsetpos(file->iofile, &save_position) == -1)
-    return -1;
+    if (fsetpos(file->iofile, &save_position) == -1)
+      return -1;
+  }
 
   /* set primary tag options and target padded length for convenience */