Xref: utzoo comp.graphics:12425 alt.graphics.pixutils:160 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!apple!well!jef From: jef@well.sf.ca.us (Jef Poskanzer) Newsgroups: comp.graphics,alt.graphics.pixutils Subject: Re: solution: pixel aspect ratio in GIF images Message-ID: <19081@well.sf.ca.us> Date: 18 Jul 90 01:05:34 GMT References: <10454@odin.corp.sgi.com> Reply-To: Jef Poskanzer Organization: Paratheo-Anametamystikhood Of Eris Esoteric, Ada Lovelace Cabal Lines: 107 In the referenced message, jindak@surfside.esd.sgi.com (Chris Schoeneman) wrote: }GIF allows for "extension blocks" which all readers must accept. So I }propose the following extension: } } 7 6 5 4 3 2 1 0 Byte # } +---------------+ } |0 0 1 0 0 0 0 1| 1 '!' - GIF extension block introducer } +---------------+ } |0 1 0 1 0 0 1 0| 2 'R' - For 'aspect Ratio' } +---------------+ } |0 0 0 0 0 0 1 0| 3 2 - Two bytes in block } +---------------+ } | pixel width | 4 - First part of ratio (numerator) } +---------------+ } | pixel height | 5 - Second part of ratio (denominator) } +---------------+ } |0 0 0 0 0 0 0 0| 6 0 - extension block end code } +---------------+ } }Let byte four equal 'x' and byte five equal 'y' Then x:y is the _pixel_ }aspect ratio. I like this. I have appended a quick patch for giftoppm.c that should (a) make it read and ignore extension blocks, and (b) make it handle this new aspect ratio extension block by putting out a message advising the user to do a ppmscale. This is the same way that ilbmtoppm handles non-square pixels. I haven't tested this patch beyond compiling it, but it's pretty simple. A very similar change should work for any other GIF readers derived from Patrick Naughton's gif2ras. If anyone modifies a GIF writer to generate these extension blocks, drop me a line so we can check interoperability. --- Jef Jef Poskanzer jef@well.sf.ca.us {ucbvax, apple, hplabs}!well!jef "I'll tell you right out, I'm a man who likes talking to a man who likes to talk." -- Kaspar Gutman [The Maltese Falcon] *** giftoppm.c.old Tue Jul 17 15:50:09 1990 --- giftoppm.c Tue Jul 17 16:10:11 1990 *************** *** 65,70 **** --- 65,72 ---- #define False (0) #define NEXTBYTE (*ptr++) + #define EXTENSION 0x21 + #define EXTENSION_ASPECTRATIO 0x52 #define IMAGESEP 0x2c #define INTERLACEMASK 0x40 #define COLORMAPMASK 0x80 *************** *** 245,253 **** Red[1] = Green[1] = Blue[1] = 255; } /* Check for image seperator */ ! if (NEXTBYTE != IMAGESEP) pm_error( "%s is a corrupt GIF file (nosep)", inf, 0,0,0,0 ); /* Now read in values from the image descriptor */ --- 247,287 ---- Red[1] = Green[1] = Blue[1] = 255; } + /* Check for extension blocks */ + + for (;;) { + ch = NEXTBYTE; + if ( ch != EXTENSION ) + break; + ch = NEXTBYTE; + if (ch == EXTENSION_ASPECTRATIO) { + int pwid, phei; + if (NEXTBYTE != 2) + pm_error( "%s is a corrupt GIF file (bad aspectratio 1)", inf, 0,0,0,0 ); + pwid = NEXTBYTE; + phei = NEXTBYTE; + if (NEXTBYTE != 0) + pm_error( "%s is a corrupt GIF file (bad aspectratio 2)", inf, 0,0,0,0 ); + if (pwid != phei) + pm_message( + "(Warning: non-square pixels; to fix do a 'ppmscale -%cscale %g'.)\n", + pwid > phei ? 'x' : 'y', + pwid > phei ? (float) pwid / phei : (float) phei / pwid, 0,0,0 ); + } else { + /* Unknown type of extension block - skip past it */ + for (;;) { + ch = NEXTBYTE; + if (ch == 0) + break; + while (--ch >= 0) + (void) NEXTBYTE; + } + } + } + /* Check for image seperator */ ! if (ch != IMAGESEP) pm_error( "%s is a corrupt GIF file (nosep)", inf, 0,0,0,0 ); /* Now read in values from the image descriptor */