2

I am using a jpeg encoder library (Jpegant) for compressing raw YCbCr images to Jpeg in C. The library works fine for a YCbCr image which has separate Y Cb and Cr components. Also in the library, the Y, Cb, and Cr streams are encoded separately and the generated bytes are written to the Jpeg file after the header.

Now I want to use the same library for encoding only the Y stream to a grayscale Jpeg image. The first step i did was to remove the Cb and Cr encoding. So only the Y stream is getting encoded and written to the file. The generated file is not a grayscale image, its just junk.

I tried doing the same by sending a stream of zeroes in both the Cb and Cr and this gives me what I want, so I assumed the issue is not in the encoding but in the headers. The header I am using is described here https://github.com/t27/vt-fox-1/tree/master/STM32L1_Code/encoder#basic-output-file

I have modified the number of streams(commented as 'nrofcomponents' in the above file) in the SOF and SOS sections. I have also removed the relevant Chrominance tables/data from the SOF,SOS and DHT sections. I set the Y subsampling to 0x11. The lengths for each of the sections are also modified. I used jpegsnoop too, and even that gives no errors.

The only problem is that most of the jpeg viewers are saying that my file is invalid and cant display it.

What else should I change in the header?

PS:I am creating a 16*8(w*h) pixel array and encoding 2 matrices of 8*8 at a time, I have set my RSI as Imagewidth/16.

Tarang Shah
  • 247
  • 4
  • 13
  • Try running `jhead -v -v -v file` to see if `jhead` can tell you anything wrong with your file encoding. – Mark Setchell Jul 11 '14 at 07:21
  • @MarkSetchell the output jhead gives with the above command is as shown here pastebin.com/E8pJEDmx I dont think theres any error in it... – Tarang Shah Jul 11 '14 at 07:53
  • How about using ImageMagick's `convert yourYchannel.jpg y.png` to see if ImageMagick tells you what is wrong and fails to convert, or converts properly and confirms your data stream is correctly encoded? – Mark Setchell Jul 11 '14 at 08:06
  • imageMagick says this http://pastebin.com/99arb7G8 I'll check on this. I am creating a 16*8(w*h) pixel array and encoding 2 matrices of 8*8 at a time, I have set my RSI as Imagewidth/16 – Tarang Shah Jul 11 '14 at 08:17

2 Answers2

3

I found a solution to this problem. Basically the header has Quantization Tables and Huffman Tables for the the Chrominance and Luminance in a colored jpeg. Also the number of streams of data(Y,Cb,Cr) is defined in the header itself. So what I did was to change the number of streams to 1 and removes the unneccessary Quantization and Huffman tables from the header. Also an important thing is the Restart interval. When using a a Y only stream, I had to set the restart interval(in the header) to double of the RSI of a YCbCr stream of YUV422 format.

The jpec library(which only encodes grayscale, compared to jpegants color encoding) was very helpful. https://github.com/Moodstocks/jpec/blob/master/src/enc.c

Tarang Shah
  • 247
  • 4
  • 13
0

IF you have a YCbCr JPEG and want to convert it to grayscale, you should be able to write a simple filter. Such a filter nearly has to remove any SOS streams (start of scans) with as scan ID other than 1. You should also need to modify the SOF frame market to set the number of components to 1.

That would be the minimum. You could also remove any DHT and DQT markers that are not referenced by scan 1.

There's not a lot to it.

It might be interesting to know here if you are using progressive of sequential JPEG. The process above would work for both but others may not.

user3344003
  • 20,574
  • 3
  • 26
  • 62
  • I dont have a YCbCr jpeg. I have a stream of raw Y data, which is basically the luminance data. I want to encode this Y data to a jpeg. As mentioned in the question – Tarang Shah Jul 14 '14 at 04:17