Jpeg calculating max size

后端 未结 5 2041
灰色年华
灰色年华 2021-02-08 00:19

I have to say the I don\'t know much about how file formats work. My question is say I have a jpeg file that is 200 px by 200 px, how can one calculate what the maximum size th

5条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-08 00:51

    There are many ways to make a 'pathological' JPEG/JFIF file that is unusually large.

    At the extreme end of the spectrum there is no limit to the size, since the standard doesn't limit some types of marker appearing more than once - e.g. a JFIF file full of many GB of DRI (define restart interval) markers and then an 8x8 pixel MCU at the end is technically valid.

    If we restrict ourselves to 'normal' marker usage then we find an upper limit as follows :

    Some background -

    1. JPEG encodes pixels as a MCU (group) of 8x8 pixel blocks (DCT blocks), one DCT block for each component (Y, Cb, Cr).

    2. To get best compression (and smallest size), a 4:2:0 chroma subsampling scheme is used where 75% of the chroma information is omitted. To get best quality (and largest size), the file is 2/3rd's chroma, 1/3rd luminance info.

    3. Huffman bitstream symbols are used to encode DCT components, of which there are up to 65 per DCT block (64 AC + 1 DC).

    4. Huffman symbols can range from 1 to 16 bits and are chosen by the encoder to be as small as possible; However, the choice of symbol length can be specified.

    5. Final encoding of the huffman bitstream must be done so that markers can be uniquely identified. I.e, any occurance of a 0xff byte in the output must be replaced by two bytes - 0xff,0x00.

    Using all this information we can construct a pathological, but valid, JPEG file which libjpeg (the most common JPEG decoder implementation) is happy to decode.

    First, we need the longest possible huffman symbols. At first thought, defining a maximal-length huffman symbol (16 bits) of all 1's, would use most space, however libjpeg refuses to handle a Huffman symbol which is all 1's, this doesn't seem to be excluded by the standard - as it still a unique symbol as the size is already known to be 16 bits unlike other variable-length symbols, and indeed some decoders can handle it (JPEGSnoop).

    So we define a huffman table which sets the last two symbols as follows :

    11111111_1111110  -> (0,0) (EOB - end of block value)
    11111111_11111110 -> (0,15)
    

    Such a huffman table would appear in a JPEG file as :

    0xFF, 0xC4 ; DHT - define huffman table
    0x00, 35 ; length
    0x00 ; DC 0
    1,1,1,1,1,1,1,1,1,1, 1, 1, 1, 1, 1, 1 ; histogram
    1,2,3,4,5,6,7,8,9,10,11,12,13,14,0,15 ; symbols
    

    Now to encode a maximal-length DCT block :

    1 x DC of 31 bits  ( 11111111 11111110 11111111 1111111 )
    64 x AC of 31 bits ( 11111111 11111110 11111111 1111111 )
    = 2015 bits
    

    Since an MCU will be 3 DCT blocks (one for each component), the MCU size will be 6045 bits.

    Most of these bytes will be 0xff, which are replaced by 0xff,0x00 in the output stream, as per the standard, in order to differentiate the bitstream from valid markers.

    Perform this mapping and a complete DCT is represented by 8 repeats of the following byte pattern :

    0xff,0x00,0xfe,0xff,0x00,0xff,0x00
    0xff,0x00,0xfd,0xff,0x00,0xff,0x00
    0xff,0x00,0xfb,0xff,0x00,0xff,0x00
    0xff,0x00,0xf7,0xff,0x00,0xff,0x00
    0xff,0x00,0xef,0xff,0x00,0xff,0x00
    0xff,0x00,0xdf,0xff,0x00,0xff,0x00
    0xff,0x00,0xbf,0xff,0x00,0xff,0x00
    0xff,0x00,0x7f,0xff,0x00
    

    which totals 8*54 = 432 bytes

    Adding all this up, we have : 3 components * (432 bytes per component) = 1296 bytes per 8x8 pixels

    a header of 339 bytes is required for the SOI/DHT/DQT/SOS segments to setup the image properties and huffman tables, a 2 byte EOI marker is required to end the image.

    Since a 200x200 image would be 25x25 MCU's, we have a final size of :

    339 + (25 * 25 * 1296) + 2 = 810341 bytes

    which works out as a little over 20.25 bytes per pixel, over 6 times larger than an uncompressed BMP/TGA.

提交回复
热议问题