ahg@mentor.cc.purdue.edu (Allen Braunsdorf) (07/17/90)
In article <9894@pt.cs.cmu.edu> tgl@zog.cs.cmu.edu (Tom Lane) writes: >In article <9866@pt.cs.cmu.edu>, I asked: >> The GIF documentation that I have makes no mention of the question of >> pixel shape. Is there any recognized convention about whether a GIF >> image is set up for square or non-square pixels, and what the assumed >> pixel aspect ratio is in the latter case? > >There seems to be general agreement that there isn't a recognized >standard for pixel aspect ratio. True and unfortunate. An image format that claims to be for interchange is worthless for exactly that purpose because of this fact. Watch my lips: Putting an image into GIF without somehow documenting the aspect ratio destroys the image. The originally intended image cannot be recovered with certainty. >Erik Talvola (talvola@janus.Berkeley.EDU) points out that a GIF picture >of size 320x200 pixels is almost surely intended for an IBM CGA display, or a Commodore 64 or an Atari ST or an Amiga.... I know for a fact that my 64 and my Amiga make different sized 320 x 200 screens on the same monitor (the 64's is narrower). Not to mention that the Amiga can make three screens that are all 320 x 200, but have different aspect ratios. >It seems to me that a workable solution for GIF files would be to >standardize on Brian's suggestion: let the screen dimensions in the >file header represent a pixel area that fills a 4x3 physical area. >A GIF reader could then rescale the image appropriately for its own >screen. > >This is something of a hack, but it has several nice properties: > 1. The file format doesn't change. > 2. Existing GIF readers don't break (since they almost > surely ignore the screen dimension info). > 3. A large fraction of the GIF files out there have correct > info in them already (namely, all the IBM-screen files). > >The main disadvantage is that readers using this convention would have >to guard against computing a bogus aspect ratio when given a GIF file >that doesn't adhere to the convention. One easy defense is to reject >any computed ratio that falls outside the expected range (probably >1.0 to 1.4 would cover it). A command-line switch to override the >aspect ratio adjustment would be a good idea too. Nonsense. I make lots of images for display on my Amiga that have pixels nearly twice as wide as they are tall. Atari 8 bits have modes where the pixels are far wider than that. A PostScript printer can print a picture of >any< size with >any< pixel aspect ratio. This "solution" is almost as narrow minded and silly as GIF is to begin with. That's by no means an attack on any of the people in this discussion, only on the idea that you can somehow determine the aspect ratio of an unknown image. It just can't be done. The only real solution is to tell the aspect ratio of the image when you post it or whatever. If somebody is going to send me a GIF, I always tell them to send the aspect ratio along with it, or forget it. Archives typically have a file that shows how many colors each file has, why not another column for pixel aspect ratio: clown.gif 657 x 395 x 8 (1:1) shuttle.gif 657 x 395 x 8 (12:7) zebra.gif 657 x 395 x 8 (4:13) That way nobody has to guess. If you guessed from just the dimensions of those images, you would have been wrong at least twice, right? >Any comments? Yeah, in general, I'm more interested in the pixel aspect ratio (the shape of the pixels) than in the image aspect ratio. Either can be computed from the other for a known image size, but I prefer the pixel dimensions. Why? Because on many displays, the image size is variable, but the pixel aspect ratio is not. Again, on my Amiga I'm free to make an screen of nearly any size, but I only have three (four really) different kinds of pixels. Posting the image aspect ratio with each of my images would be very confusing as it varies so much, but the pixel aspect ratio stays the same. I often move images from one of my machines to another. I use the pixel aspect ratios to make any necessary corrections. That way, the images don't get distorted any more than they need to. If I didn't have the aspect ratio of the image documented, or didn't know the aspect ratio of the target device, I could not do this. Assumption of aspect ratio is an evil thing. If you find you do it often, you should probably consider a different image storage format. Try IFF ILBM's, coding it up as a PostScript program, or even TIFF. I don't like the complexities of TIFF, but at least I >can< decode a TIFF. No such luck with a GIF. (Though it is easy to get the information that is encoded in a GIF, it's impossible to get what's just not there.) GIF's a toy, and a dangerous one. If you want to play with it, use a warning sticker that contains the (pixel, or at least image) aspect ratio. That way, people won't have to slaughter your images. --- Allen Braunsdorf Purdue University Computing Center cc.purdue.edu!ahg UNIX Systems Programmer
rennie@cs.albany.edu (William A Rennie) (07/17/90)
In article <12198@mentor.cc.purdue.edu> ahg@mentor.cc.purdue.edu (Allen Braunsdorf) writes: >It seems to me that a workable solution for GIF files would be to >standardize on Brian's suggestion: let the screen dimensions in the >file header represent a pixel area that fills a 4x3 physical area. >A GIF reader could then rescale the image appropriately for its own >screen. > The GIF standard written by Compuserve has hooks available for expansion. Even better, the standard assumes that all existing viewers will ignore the expansion information. (As I recall they have a header code that is supposed to mean ignore me to current viewers.) The pixel aspect ratio problem is a major one. Perhaps pressure on Compuserve would force a usable expansion. Bill Rennie rennie@cssun.albany.edu
tgl@zog.cs.cmu.edu (Tom Lane) (07/17/90)
In article <12198@mentor.cc.purdue.edu>, ahg@mentor.cc.purdue.edu (Allen Braunsdorf) writes (in response to a previous post of mine): > >It seems to me that a workable solution for GIF files would be to > >standardize on Brian's suggestion: let the screen dimensions in the > >file header represent a pixel area that fills a 4x3 physical area. > >A GIF reader could then rescale the image appropriately for its own > >screen. > > This "solution" is almost as narrow minded and silly as GIF is to begin > with. That's by no means an attack on any of the people in this > discussion, only on the idea that you can somehow determine the aspect > ratio of an unknown image. It just can't be done. How about not using "fighting words" when you don't understand the proposal? What I suggested was that the original creator of a GIF image document the image's pixel aspect ratio by redefining the meaning of a currently useless pair of numbers. It should be obvious that there is no way to regenerate this info (except by "eyeball adjustment") at any later date. > Watch my lips: Putting an image into GIF without somehow documenting > the aspect ratio destroys the image. The originally intended image > cannot be recovered with certainty. Exactly. What I'm proposing is a way to include that number without breaking the existing file format. > >The main disadvantage is that readers using this convention would have > >to guard against computing a bogus aspect ratio when given a GIF file > >that doesn't adhere to the convention. One easy defense is to reject > >any computed ratio that falls outside the expected range (probably > >1.0 to 1.4 would cover it). > > Nonsense. I make lots of images for display on my Amiga that have > pixels nearly twice as wide as they are tall. Atari 8 bits have modes > where the pixels are far wider than that. OK, I wasn't aware of that. That means the range-check couldn't be as tight as I suggested, but it doesn't render the proposal unworkable. It would be easy to extend my proposal so that image creators could unambiguously indicate that they were supplying aspect ratio data per the new interpretation: just put small numbers, say less than 64, into the "screen dimensions" fields. A reader seeing "4x3" could be certain that it was computing a valid aspect ratio correction, whereas if it saw "320x200" it might want to confirm the correction with its user. > Assumption of aspect ratio is an evil thing. If you find you do it > often, you should probably consider a different image storage format. > Try IFF ILBM's, coding it up as a PostScript program, or even TIFF. I agree, but GIF is sufficiently popular and storage-efficient that it's not likely to go away just because I don't like it. Better to offer a constructive and reasonably painless proposal for fixing it. -- tom lane Internet: tgl@cs.cmu.edu UUCP: <your favorite internet/arpanet gateway>!cs.cmu.edu!tgl BITNET: tgl%cs.cmu.edu@cmuccvma CompuServe: >internet:tgl@cs.cmu.edu
jindak@surfside.esd.sgi.com (Chris Schoeneman) (07/17/90)
In article <12198@mentor.cc.purdue.edu>, ahg@mentor.cc.purdue.edu (Allen Braunsdorf) writes: >Assumption of aspect ratio is an evil thing. And in article <9922@pt.cs.cmu.edu> tgl@zog.cs.cmu.edu (Tom Lane) writes: >I agree, but GIF is sufficiently popular and storage-efficient that >it's not likely to go away just because I don't like it. Better to >offer a constructive and reasonably painless proposal for fixing it. I agree, too. But instead of messing with the format (at least the format's meaning), why not extend GIF within it's framework? 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. 'x' and 'y' should be relatively prime (ie they should have no common divisor except one), but they don't have to be. A 640x480 image for display on a VGA graphics system (IBM), would have a 1:1 ratio, so bytes four and five would both equal one. Note that the _image_ aspect ratio is 4:3, but the pixels are square. A more extreme example would be an image designed for display on an TRS-80. It would have a ratio of 5:12, since twelve pixels are as wide as 5 pixels are high. Dividing the image's pixel aspect ratio by your machine's pixel aspect ratio gives the number of pixels across per pixel down that need to be drawn to produce the image correctly. For example, let's assume a machine with a pixel aspect ratio of 1:2 (twice as high as wide). For an image with a 1:1 pixel aspect ratio: 1 - 1 1 2 2 --- = - x - = - So we need two pixels across for each one down. 1 1 1 1 - 2 For an image with a 4:3 pixel aspect ratio: 4 - 3 4 2 8 --- = - x - = - We need eight pixels across for three down. 1 3 1 3 (Or 2.667 pixels across per one down.) - 2 The latter example points out a problem. Should the decoder draw the image with each dot made with 8x3 pixels? This is entirely up to the decoder. It could instead draw horizontally three pixels, three pixels, two pixels for three points in the image. (On the next line it might try 3,2,3, then 2,3,3, etc.) The point is however the image is drawn, the aspect ratio is correct. Comments or suggestions? -Chris Schoeneman Chris Schoeneman | I was neat, clean, shaved and sober, jindak@surfside.esd.sgi.com | and I didn't care who knew it. Silicon Graphics, Inc. | -Raymond Chandler Mountain View, CA | (The Big Sleep)
ahg@mentor.cc.purdue.edu (Allen Braunsdorf) (07/18/90)
In article <9922@pt.cs.cmu.edu> tgl@zog.cs.cmu.edu (Tom Lane) writes: >In article <12198@mentor.cc.purdue.edu>, ahg@mentor.cc.purdue.edu >(Allen Braunsdorf) writes (in response to a previous post of mine): > >How about not using "fighting words" when you don't understand the proposal? > >What I suggested was that the original creator of a GIF image document the >image's pixel aspect ratio by redefining the meaning of a currently useless >pair of numbers. It should be obvious that there is no way to regenerate >this info (except by "eyeball adjustment") at any later date. > >> Watch my lips: Putting an image into GIF without somehow documenting >> the aspect ratio destroys the image. The originally intended image >> cannot be recovered with certainty. > >Exactly. What I'm proposing is a way to include that number without >breaking the existing file format. But it does break. The screen size is in there so that multiple images stored in one file have a place to go. My GIF decoder makes a frame as big as the screen and then renders each image into this frame. And it's not just me- that's the right thing to do. If you record a bogus screen size, you could really break things. Even if it didn't break, the picture might have a really funny border around it. Multiple images in one file allow you to make a picture with many colors by breaking it up into little tiles. That way I could get more than 256 colors in a picture if I wanted. It's standard and it's useful. It's especially useful for broadcasting several little "window" pictures to a terminal. (I'm sure that was the original idea.) Since I don't use GIF locally here, my tool (giftorgb) creates three files (foo.[rgb]) that are just raw byte dumps of the frame. From that, I can process the image any way I need and then recode it into whatever format later. >I agree, but GIF is sufficiently popular and storage-efficient that >it's not likely to go away just because I don't like it. Better to >offer a constructive and reasonably painless proposal for fixing it. Another poster proposed adding a new '!' block to the format. That's the right way, and a good idea. My comments about that are under separate cover. --- Allen Braunsdorf Purdue University Computing Center cc.purdue.edu!ahg UNIX Systems Programmer
ahg@mentor.cc.purdue.edu (Allen Braunsdorf) (07/18/90)
In article <10454@odin.corp.sgi.com> jindak@surfside.esd.sgi.com (Chris Schoeneman) writes: >In article <12198@mentor.cc.purdue.edu>, ahg@mentor.cc.purdue.edu >(Allen Braunsdorf) writes: >>Assumption of aspect ratio is an evil thing. >And in article <9922@pt.cs.cmu.edu> tgl@zog.cs.cmu.edu (Tom Lane) >writes: >>I agree [but GIF is popular and efficient]. >I agree, too. But instead of messing with the format (at least the >format's meaning), why not extend GIF within it's framework? 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. 'x' and 'y' should be relatively prime (ie they should >have no common divisor except one), but they don't have to be. That's the right way, and I like it. One problem: only one of these should be allowed per file. That is, it should describe the screen's pixels and all the images in the file need to comply to it. Otherwise, it's a lot messier to decode. I dump the screen into files and then aspect ratio correct the whole thing. If the aspect ratio could change between images, I'd have to really beef up my GIF decoder. It seems to me that the whole screen should have the same kind of pixel anyway, so this limitation is in the spirit of the original idea (of several images as part of a larger graphic screen on a single device). How hard is it to amend the GIF definition? Didn't they do it a while back to allow Amiga HAM images? >The latter example points out a problem. Should the decoder draw the >image with each dot made with 8x3 pixels? This is entirely up to the >decoder. It could instead draw horizontally three pixels, three >pixels, two pixels for three points in the image. (On the next line it >might try 3,2,3, then 2,3,3, etc.) The point is however the image is >drawn, the aspect ratio is correct. If coloration is not a problem, they should probably filter the rows to fit their display. When I convert GIFs to 24 bit color images, I can do this easily, but for a 256 color display it could be difficult. Of course, users with less than a 256 color display have to recolor the image anyway, so this is probably less additional trouble there. Some of the programs I've seen don't handle some pictures very well. Usually it's because they either don't recolor or resize the pictures nicely. Do you suppose that if these programs were enhanced to use accurate aspect ratio information they might improve in other ways as a side effect? >Comments or suggestions? This extension block should come before the first image in the file and (as I said above) should apply to the whole screen. Has anybody else proposed this? It seems that someone in then PC world (with its many graphic modes with different aspect ratios) would have demanded this a long time ago. PC GIF decoders often make you pick the graphic mode to use for display. If they had this, they could use the aspect ratio and number of colors to get a really close mode match (if it came from a machine with the same graphic modes, it would be exact), or process the image to make it fit whatever mode you wanted. It sounds like a good idea to me. If this were official, I'd probably start using GIF for some things. --- Allen Braunsdorf Purdue University Computing Center cc.purdue.edu!ahg UNIX Systems Programmer
tgl@zog.cs.cmu.edu (Tom Lane) (07/18/90)
In article <10454@odin.corp.sgi.com>, jindak@surfside.esd.sgi.com (Chris Schoeneman) writes: > ... instead of messing with the format (at least the > format's meaning), why not extend GIF within it's framework? GIF > allows for "extension blocks" which all readers must accept. So I > propose the following extension: > > [ straightforward extension block defining assumed pixel aspect ratio ] That's the obvious solution, and certainly the logically cleanest one. Why did I propose hacking up the screen size values instead? Because *not all GIF readers handle extension blocks*. In particular, the two that I have here (Patrick Naughton's gif2ras and xgif) choke on any extension block. These particular two seem to be descended from a common ancestor, which may well have other progeny. Sure, these readers violate the published standard; but they are pretty widely used. Meanwhile, in article <12234@mentor.cc.purdue.edu> ahg@mentor.cc.purdue.edu (Allen Braunsdorf) writes: >The screen size is in there so that multiple images >stored in one file have a place to go. My GIF decoder makes a frame as >big as the screen and then renders each image into this frame. [I assume Allen means "makes a frame as big as the logical screen size indicated in the file header", not "as big as the display the decoder is using". I could argue that it wouldn't be difficult to handle multiple images this way without using the file's screen size, but that's really not the point here.] So what we've got are two different proposals, each of which breaks a different subset of the GIF readers currently out there. On aesthetic grounds the extension-block approach is certainly superior, but I'm not at all sure that it is superior on backwards compatibility grounds. It would be nice to get some hard data on the following points: 1. How many existing GIF readers pay any attention to the screen size numbers (as opposed to the image size)? 2. How many existing GIF readers correctly skip over unrecognized extension blocks? I don't have any easy way of finding out either of these things. Perhaps someone on the net knows the answers. Don't get me wrong --- I'd be glad to see Chris's proposal (or *any* solution) adopted. I just think that a high degree of backwards compatibility is going to be necessary to make the thing fly. I suspect that redefining the screen size fields would create fewer compatibility problems than adding an extension block. -- tom lane Internet: tgl@cs.cmu.edu UUCP: <your favorite internet/arpanet gateway>!cs.cmu.edu!tgl BITNET: tgl%cs.cmu.edu@cmuccvma CompuServe: >internet:tgl@cs.cmu.edu
jef@well.sf.ca.us (Jef Poskanzer) (07/18/90)
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 */