'How can i encode data to follow the JPEG standard?

I'm trying to loosely implement the JPEG standard, however i have issues with the entropy encoding methodology. How can i encode each 8x8 block and what am i to to with the resulted encoding? I imagine i could just do the DCT for the entire image and encode the entire image, but the standard describes the encoding as done for each block and i would like to follow this if possible.

My implementation so far:

function out = imageEncoder(image)
YCbCr = rgb2ycbcr(image);

quantizationTable = [16 11 10 16 24 40 51 61 ;
     12 12 14 19 26 28 60 55 ;
     14 13 16 24 40 57 69 56 ;
     14 17 22 29 51 87 80 62 ;
     18 22 37 56 68 109 103 77 ;
     24 35 55 64 81 104 113 92 ;
     49 64 78 87 103 121 120 101;
     72 92 95 98 112 100 103 99];

for channel = 1:3
    for height = 1 : 8 : size(YCbCr, 1) - 7
        for width = 1 : 8 : size(YCbCr, 1) - 7
            % divide image in 8x8 blocks, for each channel individually
            pixelBlock = YCbCr(height : height + 7, width : width + 7, channel);
            % center pixel block values around zero by subtracting 128
            pixelBlock = pixelBlock - 128;
            % perform DCT type 2 for each block
            dctPixelBlock = dct2(pixelBlock);
            % block quantization
            quantizedBlock = round(dctPixelBlock./quantizationTable);
            % zig-zag block traversal and entropy encoding
            zigzagOut = zigzag(quantizedBlock);
            symbol = unique(zigzagOut);
            probabilities = histcounts(zigzagOut,length(symbol))/length(zigzagOut);
            dict = huffmandict(symbol, probabilities);
            encoded = huffmanenco(zigzagOut, dict);
        end
    end
end

end

This does not seem to work as sometimes, if the 8x8 block has 64 identical values, huffmandict throws an error: Error using huffmandict (line 123) The value for n_ary must be less than or equal to the number of distinct symbols.. This should not happen as i have one symbol and one probability. Is there a better way to encode these values? zigzag is just a function that traverses the 8x8 block in the manner described by the standard and produces a 1x64 array.

Also, how should i store the resulted encoded data?



Solution 1:[1]

It looks like you don't specify n_ary yourself, so MatLab figures out itself that n_ary=1 and that's out of range for Matlab's implementation.

For JPEG, it doesn't matter. It doesn't actually matter that much for decoding which bitstrings you use for which values, as long as it's prefix-free. Huffman is just an algorithm to optimize the compression.

The special case where there's one symbol is therefore trivial. That one symbol can be encoded as the single bit 0. Technically that's sub-optimal, since we're not using the bit string 1, but it simplifies the decoder.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MSalters