bitbank2 / JPEGDEC

An optimized JPEG decoder for Arduino
Apache License 2.0
365 stars 47 forks source link

Added cropping to decode method #55

Closed andrewleek closed 3 months ago

andrewleek commented 1 year ago

Here is my attempt to add cropping to the JPEGDEC decode function. Im not sure if it is the best approach, but it appears to be working (aside from one issue which i will outline below*).

Just a reminder I am using an esp32-cam to capture jpeg images at 400x296 and display them "centered" on a 320x240 display. eg: x=40, y=28, width=320, height=240

If i simply run that full sized image through the decode function it comes in at 13.5 fps. With my code where I was pruning pixels in the jpeg draw callback and was getting 15.6 fps. And now with this new cropping code, I am getting 17 fps.

One thing that tripped me up was that it appears you have to run the JPEGDecodeMCU function on all blocks (even ones that are skipped) in order to move ahead through the jpeg data. I ended up creating a simple function called JPEGSkipMCU to handle this. Perhaps there is a cleaner way to jump/skip data in a jpeg, but I am not well versed in jpeg decoding.

*One issue I did encounter is if i tried to crop and display lower rows of pixels beyond a certain point I would get nothing on the display. (For example if I tried to crop with the following settings: x=0, y=392, width=320, height=8). It seemed to point to JPEGDecodeMCU throwing an error on line 1708:

usHuff = pFast[ulCode];
if (usHuff == 0) // invalid code
     return -1;

This only seems to happen when I set the y position of the crop above 70 or 80, which means i was skipping over lot of MCU's initially. Im not exactly sure why this is happening, but perhaps I am not updating something important in my JPEGSkipMCU function.

Any help here would be appreciated, especially if there is a simpler method to skip over parts of a jpeg without breaking the decode process.

And finally i just wanted to thank you for a great library! It's clear from walking through your code that you have put a lot of time, energy and understanding into it. Hopefully this will help add some further functionality to an already great library.

Cheers!

andrewleek commented 1 year ago

After some more sniffing around in the codebase as well as some research into huffman decoding, i was able to find the source of the y origin cropping bug mentioned in the initial PR message.

TheNitek commented 7 months ago

I came here looking for something similar, but in my case I am simply placing the image at negativ coordinates if it is to big. The draw function doesn't draw anything outside the screen anyway, so I was just wondering if parts in the negativ can be skipped. But I also like this approach and would love to see this (or something similiar) to get merged!

bitbank2 commented 3 months ago

I'm going to add an optimized crop function which accelerates the decoding of skipped blocks. These changes are not compatible with my idea.

andrewleek commented 3 months ago

Thats great to hear! I am looking forward to your optimized crop code.