Re: [FFmpeg-devel] [PATCH 2/2] avcodec/tiff: Multi-page support

2019-03-28 Thread Nick Renieris
Any news on this? Is there something I should do?

Στις Σάβ, 23 Μαρ 2019 στις 2:54 μ.μ., ο/η Carl Eugen Hoyos
 έγραψε:
>
> 2019-03-23 13:34 GMT+01:00, Paul B Mahol :
> > On 3/23/19, Carl Eugen Hoyos  wrote:
> >> 2019-03-23 9:11 GMT+01:00, Paul B Mahol :
> >>> On 3/22/19, Carl Eugen Hoyos  wrote:
> >>>> 2019-03-22 15:50 GMT+01:00, velocit...@gmail.com :
> >>>>> From: Nick Renieris 
> >>>>>
> >>>>> Option "-page N" (page index N starts from 1) can now
> >>>>> be used to specify which TIFF page/subfile to decode.
> >>>>
> >>>> What is the current behaviour?
> >>>> Shouldn't the decoder output all pages as for a video file?
> >>>
> >>> How?
> >>
> >> I would have suggested decoder flush.
>
> The word is probably "drain".
>
> > What? Can you elaborate what you think?
>
> Isn't there a return value that leads to subsequent calls of
> AVCodec->decode()?
>
> Carl Eugen
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 2/2] avcodec/tiff: Multi-page support

2019-03-28 Thread Nick Renieris
I haven't, is there a specific place that it's preferred I upload it to?

Στις Πέμ, 28 Μαρ 2019 στις 1:12 μ.μ., ο/η Paul B Mahol
 έγραψε:
>
> On 3/28/19, Nick Renieris  wrote:
> > Any news on this? Is there something I should do?
>
> Have you uploaded small tiff so this patch can be tested?
>
> >
> > Στις Σάβ, 23 Μαρ 2019 στις 2:54 μ.μ., ο/η Carl Eugen Hoyos
> >  έγραψε:
> >>
> >> 2019-03-23 13:34 GMT+01:00, Paul B Mahol :
> >> > On 3/23/19, Carl Eugen Hoyos  wrote:
> >> >> 2019-03-23 9:11 GMT+01:00, Paul B Mahol :
> >> >>> On 3/22/19, Carl Eugen Hoyos  wrote:
> >> >>>> 2019-03-22 15:50 GMT+01:00, velocit...@gmail.com
> >> >>>> :
> >> >>>>> From: Nick Renieris 
> >> >>>>>
> >> >>>>> Option "-page N" (page index N starts from 1) can now
> >> >>>>> be used to specify which TIFF page/subfile to decode.
> >> >>>>
> >> >>>> What is the current behaviour?
> >> >>>> Shouldn't the decoder output all pages as for a video file?
> >> >>>
> >> >>> How?
> >> >>
> >> >> I would have suggested decoder flush.
> >>
> >> The word is probably "drain".
> >>
> >> > What? Can you elaborate what you think?
> >>
> >> Isn't there a return value that leads to subsequent calls of
> >> AVCodec->decode()?
> >>
> >> Carl Eugen
> >> ___
> >> ffmpeg-devel mailing list
> >> ffmpeg-devel@ffmpeg.org
> >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >>
> >> To unsubscribe, visit link above, or email
> >> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> > ___
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 2/2] avcodec/tiff: Multi-page support

2019-03-28 Thread Nick Renieris
When I made the patch I did ask you on IRC whether I should upload
something and got no answer.

Στις Πέμ, 28 Μαρ 2019 στις 2:58 μ.μ., ο/η Nick Renieris
 έγραψε:
>
> I haven't, is there a specific place that it's preferred I upload it to?
>
> Στις Πέμ, 28 Μαρ 2019 στις 1:12 μ.μ., ο/η Paul B Mahol
>  έγραψε:
> >
> > On 3/28/19, Nick Renieris  wrote:
> > > Any news on this? Is there something I should do?
> >
> > Have you uploaded small tiff so this patch can be tested?
> >
> > >
> > > Στις Σάβ, 23 Μαρ 2019 στις 2:54 μ.μ., ο/η Carl Eugen Hoyos
> > >  έγραψε:
> > >>
> > >> 2019-03-23 13:34 GMT+01:00, Paul B Mahol :
> > >> > On 3/23/19, Carl Eugen Hoyos  wrote:
> > >> >> 2019-03-23 9:11 GMT+01:00, Paul B Mahol :
> > >> >>> On 3/22/19, Carl Eugen Hoyos  wrote:
> > >> >>>> 2019-03-22 15:50 GMT+01:00, velocit...@gmail.com
> > >> >>>> :
> > >> >>>>> From: Nick Renieris 
> > >> >>>>>
> > >> >>>>> Option "-page N" (page index N starts from 1) can now
> > >> >>>>> be used to specify which TIFF page/subfile to decode.
> > >> >>>>
> > >> >>>> What is the current behaviour?
> > >> >>>> Shouldn't the decoder output all pages as for a video file?
> > >> >>>
> > >> >>> How?
> > >> >>
> > >> >> I would have suggested decoder flush.
> > >>
> > >> The word is probably "drain".
> > >>
> > >> > What? Can you elaborate what you think?
> > >>
> > >> Isn't there a return value that leads to subsequent calls of
> > >> AVCodec->decode()?
> > >>
> > >> Carl Eugen
> > >> ___
> > >> ffmpeg-devel mailing list
> > >> ffmpeg-devel@ffmpeg.org
> > >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> > >>
> > >> To unsubscribe, visit link above, or email
> > >> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> > > ___
> > > ffmpeg-devel mailing list
> > > ffmpeg-devel@ffmpeg.org
> > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> > >
> > > To unsubscribe, visit link above, or email
> > > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> > ___
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 2/2] avcodec/tiff: Multi-page support

2019-03-28 Thread Nick Renieris
Ok, here's a multipage tif with 3 pages, the two first are blue and
the last one red:
https://0x0.st/zKdB.tif

Στις Πέμ, 28 Μαρ 2019 στις 4:35 μ.μ., ο/η Paul B Mahol
 έγραψε:
>
> On 3/28/19, Nick Renieris  wrote:
> > When I made the patch I did ask you on IRC whether I should upload
> > something and got no answer.
> >
>
> Please upload it, somewhere like https://0x0.st/
>
> > Στις Πέμ, 28 Μαρ 2019 στις 2:58 μ.μ., ο/η Nick Renieris
> >  έγραψε:
> >>
> >> I haven't, is there a specific place that it's preferred I upload it to?
> >>
> >> Στις Πέμ, 28 Μαρ 2019 στις 1:12 μ.μ., ο/η Paul B Mahol
> >>  έγραψε:
> >> >
> >> > On 3/28/19, Nick Renieris  wrote:
> >> > > Any news on this? Is there something I should do?
> >> >
> >> > Have you uploaded small tiff so this patch can be tested?
> >> >
> >> > >
> >> > > Στις Σάβ, 23 Μαρ 2019 στις 2:54 μ.μ., ο/η Carl Eugen Hoyos
> >> > >  έγραψε:
> >> > >>
> >> > >> 2019-03-23 13:34 GMT+01:00, Paul B Mahol :
> >> > >> > On 3/23/19, Carl Eugen Hoyos  wrote:
> >> > >> >> 2019-03-23 9:11 GMT+01:00, Paul B Mahol :
> >> > >> >>> On 3/22/19, Carl Eugen Hoyos  wrote:
> >> > >> >>>> 2019-03-22 15:50 GMT+01:00, velocit...@gmail.com
> >> > >> >>>> :
> >> > >> >>>>> From: Nick Renieris 
> >> > >> >>>>>
> >> > >> >>>>> Option "-page N" (page index N starts from 1) can now
> >> > >> >>>>> be used to specify which TIFF page/subfile to decode.
> >> > >> >>>>
> >> > >> >>>> What is the current behaviour?
> >> > >> >>>> Shouldn't the decoder output all pages as for a video file?
> >> > >> >>>
> >> > >> >>> How?
> >> > >> >>
> >> > >> >> I would have suggested decoder flush.
> >> > >>
> >> > >> The word is probably "drain".
> >> > >>
> >> > >> > What? Can you elaborate what you think?
> >> > >>
> >> > >> Isn't there a return value that leads to subsequent calls of
> >> > >> AVCodec->decode()?
> >> > >>
> >> > >> Carl Eugen
> >> > >> ___
> >> > >> ffmpeg-devel mailing list
> >> > >> ffmpeg-devel@ffmpeg.org
> >> > >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >> > >>
> >> > >> To unsubscribe, visit link above, or email
> >> > >> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> >> > > ___
> >> > > ffmpeg-devel mailing list
> >> > > ffmpeg-devel@ffmpeg.org
> >> > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >> > >
> >> > > To unsubscribe, visit link above, or email
> >> > > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> >> > ___
> >> > ffmpeg-devel mailing list
> >> > ffmpeg-devel@ffmpeg.org
> >> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >> >
> >> > To unsubscribe, visit link above, or email
> >> > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> > ___
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 2/2] avcodec/tiff: Multi-page support

2019-03-28 Thread Nick Renieris
Huh? No I fixed that, it's AV_OPT_TYPE_INT now.
See the second email in this list (first was the initial patch, then
the corrected patch).

Στις Παρ, 29 Μαρ 2019 στις 12:51 π.μ., ο/η Paul B Mahol
 έγραψε:
>
> On 3/28/19, Nick Renieris  wrote:
> > Ok, here's a multipage tif with 3 pages, the two first are blue and
> > the last one red:
> > https://0x0.st/zKdB.tif
> >
>
> Patch contains UINT16 opt and as is can not be applied.
> Please fix that.
>
> > Στις Πέμ, 28 Μαρ 2019 στις 4:35 μ.μ., ο/η Paul B Mahol
> >  έγραψε:
> >>
> >> On 3/28/19, Nick Renieris  wrote:
> >> > When I made the patch I did ask you on IRC whether I should upload
> >> > something and got no answer.
> >> >
> >>
> >> Please upload it, somewhere like https://0x0.st/
> >>
> >> > Στις Πέμ, 28 Μαρ 2019 στις 2:58 μ.μ., ο/η Nick Renieris
> >> >  έγραψε:
> >> >>
> >> >> I haven't, is there a specific place that it's preferred I upload it
> >> >> to?
> >> >>
> >> >> Στις Πέμ, 28 Μαρ 2019 στις 1:12 μ.μ., ο/η Paul B Mahol
> >> >>  έγραψε:
> >> >> >
> >> >> > On 3/28/19, Nick Renieris  wrote:
> >> >> > > Any news on this? Is there something I should do?
> >> >> >
> >> >> > Have you uploaded small tiff so this patch can be tested?
> >> >> >
> >> >> > >
> >> >> > > Στις Σάβ, 23 Μαρ 2019 στις 2:54 μ.μ., ο/η Carl Eugen Hoyos
> >> >> > >  έγραψε:
> >> >> > >>
> >> >> > >> 2019-03-23 13:34 GMT+01:00, Paul B Mahol :
> >> >> > >> > On 3/23/19, Carl Eugen Hoyos  wrote:
> >> >> > >> >> 2019-03-23 9:11 GMT+01:00, Paul B Mahol :
> >> >> > >> >>> On 3/22/19, Carl Eugen Hoyos  wrote:
> >> >> > >> >>>> 2019-03-22 15:50 GMT+01:00, velocit...@gmail.com
> >> >> > >> >>>> :
> >> >> > >> >>>>> From: Nick Renieris 
> >> >> > >> >>>>>
> >> >> > >> >>>>> Option "-page N" (page index N starts from 1) can now
> >> >> > >> >>>>> be used to specify which TIFF page/subfile to decode.
> >> >> > >> >>>>
> >> >> > >> >>>> What is the current behaviour?
> >> >> > >> >>>> Shouldn't the decoder output all pages as for a video file?
> >> >> > >> >>>
> >> >> > >> >>> How?
> >> >> > >> >>
> >> >> > >> >> I would have suggested decoder flush.
> >> >> > >>
> >> >> > >> The word is probably "drain".
> >> >> > >>
> >> >> > >> > What? Can you elaborate what you think?
> >> >> > >>
> >> >> > >> Isn't there a return value that leads to subsequent calls of
> >> >> > >> AVCodec->decode()?
> >> >> > >>
> >> >> > >> Carl Eugen
> >> >> > >> ___
> >> >> > >> ffmpeg-devel mailing list
> >> >> > >> ffmpeg-devel@ffmpeg.org
> >> >> > >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >> >> > >>
> >> >> > >> To unsubscribe, visit link above, or email
> >> >> > >> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> >> >> > > ___
> >> >> > > ffmpeg-devel mailing list
> >> >> > > ffmpeg-devel@ffmpeg.org
> >> >> > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >> >> > >
> >> >> > > To unsubscribe, visit link above, or email
> >> >> > > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> >> >> > ___
> >> >> > ffmpeg-devel mailing list
> >> >> > ffmpeg-devel@ffmpeg.org
> >> >> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >> >> >
> >> >> > To unsubscribe, visit link above, or email
> >> >> > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> >> > ___
> >> > ffmpeg-devel mailing list
> >> > ffmpeg-devel@ffmpeg.org
> >> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >> >
> >> > To unsubscribe, visit link above, or email
> >> > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> >> ___
> >> ffmpeg-devel mailing list
> >> ffmpeg-devel@ffmpeg.org
> >> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >>
> >> To unsubscribe, visit link above, or email
> >> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> > ___
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 2/2] avcodec/tiff: Multi-page support

2019-03-29 Thread Nick Renieris
Στις Παρ, 29 Μαρ 2019 στις 11:05 π.μ., ο/η Paul B Mahol
 έγραψε:
> You should also check max number of available pages.
> And issue warning if user requested more than available and than provide some
> page.

Yeah, I _would_ have done that, but the images I've seen don't
actually contain the max number of pages in PageNumber[1].
Instead, they seem to contain PageNumber[0] + 1.
Here's an example from the file I sent (generated with IrfanView):
https://i.imgur.com/CEWADrD.png
The PageNumber tag from the last IFD couldn't fit in the screenshot,
it's PageNumber[0] = 2 and PageNumber[1] = 3.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] avcodec/tiff: Add support for recognizing DNG files

2019-04-02 Thread Nick Renieris
Any consensus on using libdng?

Στις Τετ, 20 Μαρ 2019 στις 5:03 μ.μ., ο/η Nick Renieris
 έγραψε:
>
> Στις Τετ, 20 Μαρ 2019 στις 4:17 μ.μ., ο/η Paul B Mahol
>  έγραψε:
> > DNG I posted should be decodeable by default, without need for extra 
> > option(s).
>
> The DNG contents themselves? As in, not just the thumbnail? That's
> what the whole GSoC proposal is about though... What about:
> >On Tue, Mar 19, 2019 at 03:03:20AM +0200, Nick Renieris wrote:
> >Not to mention, this patch is for preliminary support, I don't suppose you 
> >require a massive patchset that implements everything altogether? Besides, 
> >GSoC requirements state that I need to get a minor patch in, before I can 
> >even apply. This is what this patch is for.
>
> > The subimage option is intended to decode Nth image as is stored in file.
>
> Nth image? The option is a boolean.
>
> _If_ it was an integer though:
>
> Given what you said, for -thumbnail I would need to check for
> NewSubfileType's Bit0==1 and for -subimage, Bit1==1?
> (Here's where I'm getting my info from so that we're on the same page:
> https://www.awaresystems.be/imaging/tiff/tifftags/newsubfiletype.html)
>
> But it's not an integer as far as I can see, so all of the above is
> out of scope for this patch.
>
> > The thumbnail option should be implemented to decode only first/best 
> > thumbnail.
>
> Sounds easy enough.
>
> > There is way to detect them and ignore them when not that option is set.
>
> Detect/ignore the thumbnails? Yes, that's easy.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] avcodec/tiff: Add support for recognizing DNG files

2019-04-02 Thread Nick Renieris
I don't mind either way, but I'm writing my GSoC proposal at the
moment and wanted an answer.

If there's no clear answer, is it something TBD that I don't need to
specify in the proposal?
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] avcodec/tiff: Add support for recognizing DNG/CinemaDNG files

2019-05-29 Thread Nick Renieris
This was meant to be a reply to
http://ffmpeg.org/pipermail/ffmpeg-devel/2019-May/244744.html
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] avcodec/tiff: Add support for recognizing DNG/CinemaDNG files

2019-05-29 Thread Nick Renieris
Do not review, I found some CinemaDNG images that do not work. I will
figure out a better solution.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH 2/2] lavc/tiff: Decode embedded JPEGs in DNG images

2019-07-23 Thread Nick Renieris
Please don't review this yet.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v2 2/2] lavc/tiff: Decode embedded JPEGs in DNG images

2019-07-23 Thread Nick Renieris
Some sample working DNGs:
https://0x0.st/z8pf.dng (non-jpeg)
https://www.kenrockwell.com/leica/m9/sample-photos-3.htm (jpeg. these
are decoded as dark because there's no color space conversion
implemented)
A few others work too but I can't find the links to them anymore, I
can upload them if requested.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v3 2/2] lavc/tiff: Decode embedded JPEGs in DNG images

2019-07-23 Thread Nick Renieris
Ready for review.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v3 2/2] lavc/tiff: Decode embedded JPEGs in DNG images

2019-07-24 Thread Nick Renieris
I have a small patch for basic gamma correction, it makes the dark
images look much better.
Should I send it here (if so, just as a single email reply to this?)
or wait until this patchset is merged?
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v3 2/2] lavc/tiff: Decode embedded JPEGs in DNG images

2019-07-24 Thread Nick Renieris
Some example DNGs before/after the gamma correction:
https://i.imgur.com/m3Qgrwb.jpg
https://i.imgur.com/XgggT2h.jpg
These are not full size of course, just screenshots.

Colors are wrong and I'm pretty sure I know why, that's TODO.


Στις Τετ, 24 Ιουλ 2019 στις 12:04 μ.μ., ο/η Nick Renieris
 έγραψε:
>
> I have a small patch for basic gamma correction, it makes the dark
> images look much better.
> Should I send it here (if so, just as a single email reply to this?)
> or wait until this patchset is merged?
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH] lavc/tiff: Decode embedded JPEGs in DNG images

2019-07-24 Thread Nick Renieris
The latest patch is unrelated to the gamma stuff (which in hindsight
isn't accurately implemented, so never mind), it has a regression fix
for z8pf.dng and adds compatibility to the following:
https://www.camerafv5.com/pages/raw-samples.php
https://www.camerafv5.com/pages/nexus6-raw-samples.php
https://www.chris-juettner.de/projekte/raw-samples-comparison-download/dji-mavic-air
etc

>Do you plan to implement camera native RGB to CIE XYZ mapping as specified
in DNG Spec 1.4.0.0 Chapter 6 ?

Perhaps. I haven't looked at it much but it may be too much work for
the time I have left, I will talk with my mentor on whether to
prioritize it (a lot of images look fine without it).

Στις Τετ, 24 Ιουλ 2019 στις 1:06 μ.μ., ο/η  έγραψε:
>
> From: Nick Renieris 
>
> Used a technique similar to lavc/tdsc.c for invoking the MJPEG decoder.
>
> This commit adds support for:
> - DNG tiles
> - DNG tile huffman lossless JPEG decoding
> - DNG color scaling [1]
>   - LinearizationTable tag
>   - BlackLevel tag
>
> [1]: As specified in the DNG Specification - Chapter 5
>
> Signed-off-by: Nick Renieris 
> ---
>  libavcodec/tiff.c | 16 
>  1 file changed, 16 deletions(-)
>
> diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
> index 423eaf0647..4f6ba256c6 100644
> --- a/libavcodec/tiff.c
> +++ b/libavcodec/tiff.c
> @@ -280,19 +280,6 @@ static void av_always_inline horizontal_fill(TiffContext 
> *s,
>   int usePtr, const uint8_t *src,
>   uint8_t c, int width, int 
> offset)
>  {
> -/* Handle DNG images with uncompressed strips (non-tiled) */
> -if (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
> TIFF_TYPE_CINEMADNG) {
> -dng_blit(s,
> - dst + offset,
> - width,
> - src,
> - width,
> - width,
> - 1,
> - 0);
> -return;
> -}
> -
>  switch (bpp) {
>  case 1:
>  while (--width >= 0) {
> @@ -1799,9 +1786,6 @@ again:
>  } else if (s->is_tiled) {
>  av_log(avctx, AV_LOG_ERROR, "DNG uncompressed tiled images are 
> not supported\n");
>  return AVERROR_PATCHWELCOME;
> -} else if (s->bpp != 8) {
> -av_log(avctx, AV_LOG_ERROR, "DNG uncompressed non-tiled non-8bpp 
> images are not supported\n");
> -return AVERROR_PATCHWELCOME;
>  }
>  }
>
> --
> 2.21.0.windows.1
>
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v6 2/2] lavc/tiff: Decode embedded JPEGs in DNG images

2019-07-25 Thread Nick Renieris
Thanks for the review Moritz, pushed fixes.

"outputted" is a word actually :)
https://forum.wordreference.com/threads/is-outputted-a-word.2707379

Στις Πέμ, 25 Ιουλ 2019 στις 4:57 μ.μ., ο/η Moritz Barsnick
 έγραψε:
>
> On Thu, Jul 25, 2019 at 15:12:53 +0300, velocit...@gmail.com wrote:
>
> Nit:
>
> >  tiff_decoder_suggest="zlib lzma"
> >  tiff_encoder_suggest="zlib"
> > +tiff_decoder_select="mjpeg_decoder"
> >  truehd_decoder_select="mlp_parser"
>
> You should pair the new decoder line with the other decoder line, not
> place it below the encoder.
>
> > +int is_jpeg; // 0 - Not JPEG, 1 - JPEG, 2 - New JPEG
>
> "is" makes this sound boolean, perhaps better "jpeg_type" or something
> like that.
>
> OTOH, I can't find the differentiation between 1 and 2 used anywhere.
>
> > +// Lookup table lookup
> > +if (lut) value = lut[value];
>
> You probably need to break the line, according to ffmpeg coding rules.
>
> > +float scale_factor;
> > +
> > +scale_factor = 1.0 / (s->white_level - s->black_level);
>
> This is promoting the floating point operation to a double precision
> operation (significant for some platforms). Either use double variables
> in the first place - if the extra precision can be justified - or use
> the "f" suffix to the constant: "1.0f".
>
> > +ret = avcodec_receive_frame(s->avctx_mjpeg, s->jpgframe);
> > +if (ret < 0) {
> > +av_log(avctx, AV_LOG_ERROR, "JPEG decoding error (%d).\n", ret);
>
> I believe the return value can be decoded into a string, e.g. with
> av_err2str().
>
> > +/* Copy the outputted tile's pixels from 'jpgframe' to to 'frame' 
> > (final buffer */
>
> Outputted is not a word. ;-) Don't worry about that, but there's a
> duplicate "to" in there, and the bracket is not closed.
>
> > +uint32_t lut_offset = value;
> > +uint32_t lut_size = count;
> > +uint32_t lut_wanted_size = 1 << s->bpp;
> > +if (lut_wanted_size != lut_size)
> > +av_log(s->avctx, AV_LOG_WARNING, "DNG contains LUT with 
> > invalid size (%d), disabling LUT\n", lut_size);
> > +else if (lut_offset >= bytestream2_size(&s->gb))
> > +av_log(s->avctx, AV_LOG_WARNING, "DNG contains LUT with 
> > invalid offset (%d), disabling LUT\n", lut_offset);
>
> Nit: the proper format identifier for uint32_t is '"%" PRIu32'. (
>
> > +} else {
> > +av_log(avctx, AV_LOG_ERROR, "DNG JPG-compressed 
> > non-bayer-encoded images are not supported\n");
> > +return AVERROR_PATCHWELCOME;
>
> Alternatively (to av_log()) use avpriv_report_missing_feature().
>
> > +}
> > +} else if (s->is_tiled) {
> > +av_log(avctx, AV_LOG_ERROR, "DNG uncompressed tiled images are 
> > not supported\n");
> > +return AVERROR_PATCHWELCOME;
>
> Ditto.
>
> > +s->jpgframe = av_frame_alloc();
> > +if (!s->jpgframe)
> > +return AVERROR(ENOMEM);
> > +
> > +/* Prepare everything needed for JPEG decoding */
> > +codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
> > +if (!codec)
> > +return AVERROR_BUG;
> > +s->avctx_mjpeg = avcodec_alloc_context3(codec);
> > +if (!s->avctx_mjpeg)
> > +return AVERROR(ENOMEM);
>
> Don't you need to free s->jpgframe here? (And codec?)
>
> Cheers,
> Moritz
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v7 2/2] lavc/tiff: Decode embedded JPEGs in DNG images

2019-07-26 Thread Nick Renieris
Στις Παρ, 26 Ιουλ 2019 στις 2:21 π.μ., ο/η Reimar Döffinger
 έγραψε:
>
> On 25.07.2019, at 17:35, velocit...@gmail.com wrote:
>
> > +// Lookup table lookup
> > +if (lut)
> > +value = lut[value];
>
> As this function is in the innermost loop, doing the if here instead of 
> having 2 different implementations is likely not ideal speed-wise.

If this were C++ this'd be trivial, but as it stands I don't see a way
to do this without sacrificing code readability and/or size.
I believe branch prediction and instruction pipelining will hide this
delay. I doubt it has any measurable effect on performance.

> > +// Color scaling
> > +value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
> > 0x));
>
> As input and output are both 16 bit I wonder if floating-point isn't rather 
> overkill compared to doing fixed-point arithmetic.

Scaling in the [0.0, 1.0] range is mentioned in the DNG spec and it's
also what dcraw does.

> >
> > +if (is_u16) {
> > +for (line = 0; line < height; line++) {
> > +uint16_t *dst_u16 = (uint16_t *)dst;
> > +uint16_t *src_u16 = (uint16_t *)src;
> > +
> > +for (col = 0; col < width; col++)
> > +*dst_u16++ = dng_raw_to_linear16(*src_u16++, s->dng_lut, 
> > s->black_level, scale_factor);
> > +
> > +dst += dst_stride * sizeof(uint16_t);
> > +src += src_stride * sizeof(uint16_t);
>
> Is all this casting working correctly on e.g. big-endian?

Not sure, I don't see why not, considering I've seen such casting in
other parts of ffmpeg.

> Also using sizeof on uint16_t and uint8_t seems a bit overkill.

It makes the programmer's intention clear, I think that's worth the
few extra characters.

> Also not sure if since these are essentially brightness/contrast adjustments 
> if we should't rather just have a way to export the transform to use...

Export to where? I don't see why you'd need to complicate this by
calling into other components, the transformation code is concise,
clear and accurate for this use case.

>
> > @@ -1519,6 +1773,26 @@ again:
> > return AVERROR_INVALIDDATA;
> > }
> >
> > +/* Handle DNG images with JPEG-compressed tiles */
> > +
> > +if (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
> > TIFF_TYPE_CINEMADNG) {
> > +if (s->is_jpeg) {
> > +if (s->is_bayer) {
> > +if ((ret = dng_decode(avctx, (AVFrame*)data, avpkt)) > 0)
> > +*got_frame = 1;
> > +return ret;
> > +} else {
> > +avpriv_report_missing_feature(avctx, "DNG JPG-compressed 
> > non-bayer-encoded images");
> > +return AVERROR_PATCHWELCOME;
> > +}
> > +} else if (s->is_tiled) {
> > +avpriv_report_missing_feature(avctx, "DNG uncompressed tiled 
> > images");
> > +return AVERROR_PATCHWELCOME;
> > +}
>
> There is no need for an "else" block if the "if" block ends in a return.

Indeed, but in my opinion it makes the code clearer on first glance
(if you miss the return). I can change it if you insist.

> Also putting the error handling first/at the deepest indentation level 
> results in more readable code generally.

That's true, I will do that.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v7 2/2] lavc/tiff: Decode embedded JPEGs in DNG images

2019-07-28 Thread Nick Renieris
Στις Κυρ, 28 Ιουλ 2019 στις 1:30 π.μ., ο/η Reimar Döffinger
 έγραψε:
>
> Huh? Are you thinking of templates? always_inline can usually be used the 
> same way.
> I haven't looked into the how or anything, it was just a comment in principle.

You're totally right (I checked on godbolt just to make sure), I
hadn't considered that. Would need a trivial change (plus the function
is already inlined) so I'll do it.

> > I believe branch prediction and instruction pipelining will hide this
> > delay. I doubt it has any measurable effect on performance.
>
> There are CPUs without that.

Yes, but with neither? Branch prediction, sure, but I'd like to hear
one example of a CPU FFmpeg runs on without pipelining (I genuinely
don't know if there are).

> Of course would need to look at what the actual requirements are concerning 
> precision, rounding and range. But that should be done anyway.
Like I said, I did. It's not possible :)

> Well, I did not find it obvious where src and dst are from and what format 
> they are in.
> Essentially if they are decoder output it's likely fine, if they are read 
> from a file without decoding step it's likely wrong.

Right, I see your concern. They are read from a file and they can be
both LE/BE, but that's specified in the file and there is logic in
tiff.c to account for it. So when we process them they are guaranteed
to be the same endianness as the host.

> >> Also not sure if since these are essentially brightness/contrast 
> >> adjustments if we should't rather just have a way to export the transform 
> >> to use...
> >
> > Export to where?
>
> Just provide as metadata and leave to e.g. libavfilter.

Not sure how I'd do that or if it'd be appropriate/feasible.

> > I don't see why you'd need to complicate this by
> > calling into other components, the transformation code is concise,
> > clear and accurate for this use case.
>
> Slow and unoptimized and in it's current form hard to SIMD optimize, 
> especially without changing output as well though (in addition to the large 
> bit width of floats reducing the benefit, denormals can be an issue for 
> SIMD-accelerating float code).
> Unless I miss a reason why nobody would ever want this to be faster?

I'll take out the comparison which should make it faster, I'll talk
with my mentor if he thinks I should use libavfilter.

> >> There is no need for an "else" block if the "if" block ends in a return.
> >
> > Indeed, but in my opinion it makes the code clearer on first glance
> > (if you miss the return). I can change it if you insist.
>
> The second comment was the more relevant one actually.
> I only really care about finding some way to make this part a whole lot more 
> readable.

Ok, hopefully the code I posted right after your review is readable enough.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v7 2/2] lavc/tiff: Decode embedded JPEGs in DNG images

2019-07-28 Thread Nick Renieris
Actually, I checked a more accurate version of my loop, and GCC
optimizes away the LUT check anyway:
https://godbolt.org/z/G1e1R4
As you can see it's smart enough to create 2 versions of my functions
(started at L3 with a lookup and L7 without it) and it does the check
outside.

There's no guarantee this is happening with the actual version of
course (it could be slower, or even faster if it also optimizes it
through dng_blit).
I could check the actual disasm in FFmpeg, but I don't think it's
worth it at this point (my mentor agrees).

Στις Κυρ, 28 Ιουλ 2019 στις 10:40 π.μ., ο/η Nick Renieris
 έγραψε:
>
> Στις Κυρ, 28 Ιουλ 2019 στις 1:30 π.μ., ο/η Reimar Döffinger
>  έγραψε:
> >
> > Huh? Are you thinking of templates? always_inline can usually be used the 
> > same way.
> > I haven't looked into the how or anything, it was just a comment in 
> > principle.
>
> You're totally right (I checked on godbolt just to make sure), I
> hadn't considered that. Would need a trivial change (plus the function
> is already inlined) so I'll do it.
>
> > > I believe branch prediction and instruction pipelining will hide this
> > > delay. I doubt it has any measurable effect on performance.
> >
> > There are CPUs without that.
>
> Yes, but with neither? Branch prediction, sure, but I'd like to hear
> one example of a CPU FFmpeg runs on without pipelining (I genuinely
> don't know if there are).
>
> > Of course would need to look at what the actual requirements are concerning 
> > precision, rounding and range. But that should be done anyway.
> Like I said, I did. It's not possible :)
>
> > Well, I did not find it obvious where src and dst are from and what format 
> > they are in.
> > Essentially if they are decoder output it's likely fine, if they are read 
> > from a file without decoding step it's likely wrong.
>
> Right, I see your concern. They are read from a file and they can be
> both LE/BE, but that's specified in the file and there is logic in
> tiff.c to account for it. So when we process them they are guaranteed
> to be the same endianness as the host.
>
> > >> Also not sure if since these are essentially brightness/contrast 
> > >> adjustments if we should't rather just have a way to export the 
> > >> transform to use...
> > >
> > > Export to where?
> >
> > Just provide as metadata and leave to e.g. libavfilter.
>
> Not sure how I'd do that or if it'd be appropriate/feasible.
>
> > > I don't see why you'd need to complicate this by
> > > calling into other components, the transformation code is concise,
> > > clear and accurate for this use case.
> >
> > Slow and unoptimized and in it's current form hard to SIMD optimize, 
> > especially without changing output as well though (in addition to the large 
> > bit width of floats reducing the benefit, denormals can be an issue for 
> > SIMD-accelerating float code).
> > Unless I miss a reason why nobody would ever want this to be faster?
>
> I'll take out the comparison which should make it faster, I'll talk
> with my mentor if he thinks I should use libavfilter.
>
> > >> There is no need for an "else" block if the "if" block ends in a return.
> > >
> > > Indeed, but in my opinion it makes the code clearer on first glance
> > > (if you miss the return). I can change it if you insist.
> >
> > The second comment was the more relevant one actually.
> > I only really care about finding some way to make this part a whole lot 
> > more readable.
>
> Ok, hopefully the code I posted right after your review is readable enough.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v9 1/2] lavc/mjpegdec: Decode Huffman-coded lossless JPEGs embedded in DNGs

2019-08-07 Thread Nick Renieris
Going to post a new patchset with my latest work. It includes these 2
commits (one slightly modified) and 11 more.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v10 04/13] lavc/tiff: Apply color scaling to uncompressed DNGs

2019-08-08 Thread Nick Renieris
Thanks for the review Michael, pushing fixes and a commit that makes
some more images compatible.

Στις Πέμ, 8 Αυγ 2019 στις 1:22 π.μ., ο/η Michael Niedermayer
 έγραψε:
>
> On Wed, Aug 07, 2019 at 06:27:14PM +0300, velocit...@gmail.com wrote:
> > From: Nick Renieris 
> >
> > Signed-off-by: Nick Renieris 
> > ---
> >  libavcodec/tiff.c | 22 +-
> >  1 file changed, 21 insertions(+), 1 deletion(-)
> >
> > diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
> > index c7e2adb3ae..b6f626daca 100644
> > --- a/libavcodec/tiff.c
> > +++ b/libavcodec/tiff.c
> > @@ -679,6 +679,25 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame 
> > *p, uint8_t *dst, int strid
> >  for (i = 0; i < width; i++)
> >  dst[i] = ff_reverse[src[i]];
> >  }
> > +
> > +/* Color processing for DNG images with uncompressed strips 
> > (non-tiled) */
> > +if (is_dng) {
>
> This variable is only added in a later patch
> so this does not build
>
> also some change in this patchset breaks:
> ./ffplay tickets/2826/pred6disc7.jpg
> file should be here:
> https://trac.ffmpeg.org/raw-attachment/ticket/2826/pred6disc7.jpg
>
> Thanks
>
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> Does the universe only have a finite lifespan? No, its going to go on
> forever, its just that you wont like living in it. -- Hiranya Peiri
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 01/14] lavc/mjpegdec: Decode Huffman-coded lossless JPEGs embedded in DNGs

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Main image data in DNGs is usually comprised of tiles, each of which is a 
Huffman-encoded lossless JPEG.

Tested for ljpeg regressions with:
`ffmpeg -f lavfi -i testsrc=d=1 -vcodec ljpeg test.avi`
`ffmpeg test.avi out.avi`
The modified code in ljpeg_decode_rgb_scan runs without issues.

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 52 +--
 libavcodec/mjpegdec.h |  1 +
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index a65bc8df15..6391107f78 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -412,6 +412,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 return AVERROR_PATCHWELCOME;
 }
 
+/* Lossless JPEGs encoded in DNGs are commonly bayer-encoded. They contain 
2
+   interleaved components and the width stored in their SOF3 markers is the
+   width of each one.  We only output a single component, therefore we need
+   to adjust the output image width. */
+if (s->lossless == 1 && nb_components == 2) {
+s->bayer = 1;
+width *= 2;
+}
 
 /* if different size, realloc/alloc picture */
 if (width != s->width || height != s->height || bits != s->bits ||
@@ -488,6 +496,9 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 }
 
 switch (pix_fmt_id) {
+case 0x: /* for bayer-encoded huffman lossless JPEGs embedded 
in DNGs */
+s->avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
+break;
 case 0x1100:
 if (s->rgb)
 s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_BGR24 : 
AV_PIX_FMT_BGR48;
@@ -1041,17 +1052,20 @@ static int handle_rstn(MJpegDecodeContext *s, int 
nb_components)
 return reset;
 }
 
+/* Handles 1 to 4 components */
 static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int 
predictor, int point_transform)
 {
 int i, mb_x, mb_y;
+unsigned width;
 uint16_t (*buffer)[4];
 int left[4], top[4], topleft[4];
 const int linesize = s->linesize[0];
 const int mask = ((1 << s->bits) - 1) << point_transform;
 int resync_mb_y = 0;
 int resync_mb_x = 0;
+int vpred[6];
 
-if (s->nb_components != 3 && s->nb_components != 4)
+if (s->nb_components <= 0 || s->nb_components > 4)
 return AVERROR_INVALIDDATA;
 if (s->v_max != 1 || s->h_max != 1 || !s->lossless)
 return AVERROR_INVALIDDATA;
@@ -1059,8 +1073,15 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 
 s->restart_count = s->restart_interval;
 
-av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size,
-   (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0]));
+if (s->restart_interval == 0)
+s->restart_interval = INT_MAX;
+
+if (s->bayer)
+width = s->mb_width / nb_components; /* Interleaved, width stored is 
the total so need to divide */
+else
+width = s->mb_width;
+
+av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, width * 4 * 
sizeof(s->ljpeg_buffer[0][0]));
 if (!s->ljpeg_buffer)
 return AVERROR(ENOMEM);
 
@@ -1078,7 +1099,12 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 for (i = 0; i < 4; i++)
 top[i] = left[i] = topleft[i] = buffer[0][i];
 
-for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+if ((mb_y * s->width) % s->restart_interval == 0) {
+for (i = 0; i < 6; i++)
+vpred[i] = 1 << (s->bits-1);
+}
+
+for (mb_x = 0; mb_x < width; mb_x++) {
 int modified_predictor = predictor;
 
 if (get_bits_left(&s->gb) < 1) {
@@ -1102,12 +1128,19 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 topleft[i] = top[i];
 top[i] = buffer[mb_x][i];
 
-PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
-
 dc = mjpeg_decode_dc(s, s->dc_index[i]);
 if(dc == 0xF)
 return -1;
 
+if (!s->bayer || mb_x) {
+pred = left[i];
+} else { /* This path runs only for the first line in bayer 
images */
+vpred[i] += dc;
+pred = vpred[i] - dc;
+}
+
+PREDICT(pred, topleft[i], top[i], pred, modified_predictor);
+
 left[i] = buffer[mb_x][i] =
 mask & (pred + (unsigned)(dc * (1 << point_transform)));
 }
@@ -1151,6 +1184,11 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 ptr[

[FFmpeg-devel] [PATCH v12 10/14] lavc/tiff: Support decoding of DNGs with single-component JPEGs

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

This enables decoding of DNG images generated by the 'DJI Zenmuse X7'
digital camera
Samples: https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 61 +++
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index cf8965453c..ecd87c0b2f 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -274,7 +274,8 @@ static int add_metadata(int count, int type,
 }
 
 static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
-  const uint8_t *src, int src_stride, int 
width, int height, int is_u16);
+  const uint8_t *src, int src_stride, int 
width, int height,
+  int is_single_comp, int is_u16);
 
 static void av_always_inline horizontal_fill(TiffContext *s,
  unsigned int bpp, uint8_t* dst,
@@ -698,6 +699,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
  0, // no stride, only 1 line
  width / pixel_size_bytes * pixel_size_bits / s->bpp, 
// need to account for [1, 16] bpp
  1,
+ 0, // single-component variation is only preset in 
JPEG-encoded DNGs
  is_u16);
 }
 
@@ -795,18 +797,32 @@ static uint16_t av_always_inline 
dng_process_color8(uint16_t value,
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
  const uint8_t *src, int src_stride,
- int width, int height, int is_u16)
+ int width, int height, int is_single_comp, int is_u16)
 {
 int line, col;
 float scale_factor;
 
 scale_factor = 1.0f / (s->white_level - s->black_level);
 
-if (is_u16) {
-for (line = 0; line < height; line++) {
+if (is_single_comp) {
+if (!is_u16)
+return; /* <= 8bpp unsupported */
+
+/* Image is double the width and half the height we need, each row 
comprises 2 rows of the output
+   (split vertically in the middle). */
+for (line = 0; line < height / 2; line++) {
 uint16_t *dst_u16 = (uint16_t *)dst;
 uint16_t *src_u16 = (uint16_t *)src;
 
+/* Blit first half of input row row to initial row of output */
+for (col = 0; col < width; col++)
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+
+/* Advance the destination pointer by a row (source pointer 
remains in the same place) */
+dst += dst_stride * sizeof(uint16_t);
+dst_u16 = (uint16_t *)dst;
+
+/* Blit second half of input row row to next row of output */
 for (col = 0; col < width; col++)
 *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
 
@@ -814,12 +830,27 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 src += src_stride * sizeof(uint16_t);
 }
 } else {
-for (line = 0; line < height; line++) {
-for (col = 0; col < width; col++)
-*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
+/* Input and output image are the same size and the MJpeg decoder has 
done per-component
+   deinterleaving, so blitting here is straightforward. */
+if (is_u16) {
+for (line = 0; line < height; line++) {
+uint16_t *dst_u16 = (uint16_t *)dst;
+uint16_t *src_u16 = (uint16_t *)src;
+
+for (col = 0; col < width; col++)
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+
+dst += dst_stride * sizeof(uint16_t);
+src += src_stride * sizeof(uint16_t);
+}
+} else {
+for (line = 0; line < height; line++) {
+for (col = 0; col < width; col++)
+*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
 
-dst += dst_stride;
-src += src_stride;
+dst += dst_stride;
+src += src_stride;
+}
 }
 }
 }
@@ -831,7 +862,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 AVPacket jpkt;
 uint8_t *dst_data, *src_data;
 uint32_t dst_offset; /* offset from dst buffer in pixels */
-int is_u16, pixel_size;
+int is_single_comp, is_u16, pixel_size;
 int ret;
 
 /* Prepare a packet and send to the MJPEG decoder */
@@ -865,9 +896,18 @@ static int dng_decode_jpeg_tile(AVCod

[FFmpeg-devel] [PATCH v12 05/14] lavc/jpegtables: Handle multiple mappings to the same value

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Some JPEGs [1] have incorrect DHT entries that map 2 codes to
the same value.

The second (last) mapping does not ever actually appear in the
code stream, therefore ignoring any mappings after the first one
fixes this.

Without this, an "mjpeg_decode_dc: bad vlc: 0:0" error is thrown.

---

[1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
 https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/jpegtables.c | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/libavcodec/jpegtables.c b/libavcodec/jpegtables.c
index cbe5523cb4..6f596cfc92 100644
--- a/libavcodec/jpegtables.c
+++ b/libavcodec/jpegtables.c
@@ -130,14 +130,27 @@ void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, 
uint16_t *huff_code,
 {
 int i, j, k,nb, code, sym;
 
-code = 0;
+/* Zero-initialize huff_size (needed for multiple mappings check below) */
+k = 0;
+for(i=1;i<=16;i++) {
+nb = bits_table[i];
+for(j=0;jhttps://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 06/14] lavc/tiff: Fix edge case with full-length/width tiles

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

In an image [1], the height was equal to the tile length (full-height
tile) and after `height % tile_length` was applied to them with the
current code, it resulted in the operating tile_length to be 0.  This
commit makes this leftover logic only applies if it's necessary.

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 4620508d53..37fda15162 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -887,10 +887,14 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 int tile_byte_count_offset, tile_byte_count;
 int tile_count_x, tile_count_y;
 int tile_width, tile_length;
+int has_width_leftover, has_height_leftover;
 int tile_x = 0, tile_y = 0;
 int pos_x = 0, pos_y = 0;
 int ret;
 
+has_width_leftover = (s->width % s->tile_width != 0);
+has_height_leftover = (s->height % s->tile_length != 0);
+
 /* Calculate tile counts (round up) */
 tile_count_x = (s->width + s->tile_width - 1) / s->tile_width;
 tile_count_y = (s->height + s->tile_length - 1) / s->tile_length;
@@ -900,12 +904,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 tile_x = tile_idx % tile_count_x;
 tile_y = tile_idx / tile_count_x;
 
-if (tile_x == tile_count_x - 1) // If on the right edge
+if (has_width_leftover && tile_x == tile_count_x - 1) // If on the 
right-most tile
 tile_width = s->width % s->tile_width;
 else
 tile_width = s->tile_width;
 
-if (tile_y == tile_count_y - 1) // If on the bottom edge
+if (has_height_leftover && tile_y == tile_count_y - 1) // If on the 
bottom-most tile
 tile_length = s->height % s->tile_length;
 else
 tile_length = s->tile_length;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 08/14] lavc/tiff: Force DNG pixel data endianness on an edge case

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 174ca168c6..9d20763186 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1038,6 +1038,18 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
AV_RL32(s->pattern));
 return AVERROR_PATCHWELCOME;
 }
+/* Force endianness as mentioned in 'DNG Specification: Chapter 3: 
BitsPerSample'
+NOTE: The spec actually specifies big-endian, not sure why we need 
little-endian,
+  but such images don't work otherwise. */
+if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)
+&& (s->bpp != 8 && s->bpp != 16 && s->bpp != 32)) {
+switch (s->avctx->pix_fmt) {
+case AV_PIX_FMT_BAYER_RGGB16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_RGGB16LE; break;
+case AV_PIX_FMT_BAYER_BGGR16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_BGGR16LE; break;
+case AV_PIX_FMT_BAYER_GBRG16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_GBRG16LE; break;
+case AV_PIX_FMT_BAYER_GRBG16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_GRBG16LE; break;
+}
+}
 break;
 case 10161:
 switch (AV_RL32(s->pattern)) {
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 07/14] lavc/tiff: Don't apply strips-related logic to tiled images

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 42 ++
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 37fda15162..174ca168c6 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1780,7 +1780,7 @@ again:
 }
 }
 
-if (!s->strippos && !s->stripoff) {
+if (!s->is_tiled && !s->strippos && !s->stripoff) {
 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
 return AVERROR_INVALIDDATA;
 }
@@ -1788,27 +1788,29 @@ again:
 if ((ret = init_image(s, &frame)) < 0)
 return ret;
 
-if (s->strips == 1 && !s->stripsize) {
-av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
-s->stripsize = avpkt->size - s->stripoff;
-}
+if (!s->is_tiled) {
+if (s->strips == 1 && !s->stripsize) {
+av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
+s->stripsize = avpkt->size - s->stripoff;
+}
 
-if (s->stripsizesoff) {
-if (s->stripsizesoff >= (unsigned)avpkt->size)
-return AVERROR_INVALIDDATA;
-bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
- avpkt->size - s->stripsizesoff);
-}
-if (s->strippos) {
-if (s->strippos >= (unsigned)avpkt->size)
-return AVERROR_INVALIDDATA;
-bytestream2_init(&stripdata, avpkt->data + s->strippos,
- avpkt->size - s->strippos);
-}
+if (s->stripsizesoff) {
+if (s->stripsizesoff >= (unsigned)avpkt->size)
+return AVERROR_INVALIDDATA;
+bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
+avpkt->size - s->stripsizesoff);
+}
+if (s->strippos) {
+if (s->strippos >= (unsigned)avpkt->size)
+return AVERROR_INVALIDDATA;
+bytestream2_init(&stripdata, avpkt->data + s->strippos,
+avpkt->size - s->strippos);
+}
 
-if (s->rps <= 0 || s->rps % s->subsampling[1]) {
-av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
-return AVERROR_INVALIDDATA;
+if (s->rps <= 0 || s->rps % s->subsampling[1]) {
+av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
+return AVERROR_INVALIDDATA;
+}
 }
 
 /* Handle DNG images with JPEG-compressed tiles */
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 12/14] lavc/mjpegdec: Skip useless APPx marker on bayer images

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Samples:
- Embedded JPEG images in the DNG images here:
  https://www.photographyblog.com/previews/pentax_k1_photos

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 0a920a7144..e7b273a363 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1807,8 +1807,15 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
 int len, id, i;
 
 len = get_bits(&s->gb, 16);
-if (len < 6)
-return AVERROR_INVALIDDATA;
+if (len < 6) {
+if (s->bayer) {
+// Pentax K-1 (digital camera) JPEG images embedded in DNG images 
contain useless APP0 markers
+av_log(s->avctx, AV_LOG_WARNING, "skipping APPx (len=%"PRId32") 
for bayer-encoded image\n", len);
+skip_bits(&s->gb, len);
+return 0;
+} else
+return AVERROR_INVALIDDATA;
+}
 if (8 * len > get_bits_left(&s->gb))
 return AVERROR_INVALIDDATA;
 
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 14/14] lavc/tiff: Initialize WhiteLevel DNG tag value

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Inited to (2^BitsPerSample)-1 as per the DNG Specification

This fixes decoding for "X7 CinemaDNG" samples here:
- https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index b9aa4efd02..aeb80a70a9 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1773,6 +1773,7 @@ static int decode_frame(AVCodecContext *avctx,
 GetByteContext stripsizes;
 GetByteContext stripdata;
 int retry_for_subifd, retry_for_page;
+int is_dng;
 
 bytestream2_init(&s->gb, avpkt->data, avpkt->size);
 
@@ -1841,6 +1842,10 @@ again:
 goto again;
 }
 
+/* At this point we've decided on which (Sub)IFD to process */
+
+is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+
 for (i = 0; igeotag_count; i++) {
 const char *keyname = get_geokey_name(s->geotags[i].key);
 if (!keyname) {
@@ -1858,10 +1863,13 @@ again:
 }
 }
 
+s->white_level = (1 << s->bpp) - 1; /* Default value as per the spec */
+
 if (!s->is_tiled && !s->strippos && !s->stripoff) {
 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
 return AVERROR_INVALIDDATA;
 }
+
 /* now we have the data and may start decoding */
 if ((ret = init_image(s, &frame)) < 0)
 return ret;
@@ -1893,7 +1901,7 @@ again:
 
 /* Handle DNG images with JPEG-compressed tiles */
 
-if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG) 
&& s->is_tiled) {
+if (is_dng && s->is_tiled) {
 if (!s->is_jpeg) {
 avpriv_report_missing_feature(avctx, "DNG uncompressed tiled 
images");
 return AVERROR_PATCHWELCOME;
@@ -2051,8 +2059,7 @@ again:
 FFSWAP(int,  p->linesize[0], p->linesize[1]);
 }
 
-if (s->is_bayer && s->white_level && s->bpp == 16 &&
-!(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)) {
+if (s->is_bayer && s->bpp == 16 && !is_dng && (s->white_level != (1 << 
s->bpp) - 1)) {
 uint16_t *dst = (uint16_t *)p->data[0];
 for (i = 0; i < s->height; i++) {
 for (j = 0; j < s->width; j++)
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 11/14] lavc/tiff: Decode 14-bit DNG images

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Sample file: 
https://drive.google.com/open?id=0B4JyRT3Lth5HVndyOTVOdWktM3J4TFEydTk1MnY3RWlpSzVB

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index ecd87c0b2f..0d931641c2 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -309,14 +309,18 @@ static void av_always_inline horizontal_fill(TiffContext 
*s,
 dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4;
 }
 break;
-case 12: {
- uint16_t *dst16 = (uint16_t *)dst;
- GetBitContext gb;
- init_get_bits8(&gb, src, width);
- for (int i = 0; i < s->width; i++) {
- dst16[i] = get_bits(&gb, 12) << 4;
- }
- }
+case 12:
+case 14: {
+uint16_t *dst16 = (uint16_t *)dst;
+int is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+uint8_t shift = is_dng ? 0 : 16 - bpp;
+GetBitContext gb;
+
+init_get_bits8(&gb, src, width);
+for (int i = 0; i < s->width; i++) {
+dst16[i] = get_bits(&gb, bpp) << shift;
+}
+}
 break;
 default:
 if (usePtr) {
@@ -1068,6 +1072,7 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
 }
 break;
 case 10121:
+case 10141:
 switch (AV_RL32(s->pattern)) {
 case 0x02010100:
 s->avctx->pix_fmt = s->le ? AV_PIX_FMT_BAYER_RGGB16LE : 
AV_PIX_FMT_BAYER_RGGB16BE;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 02/14] lavc/tiff: Decode embedded JPEGs in DNG images

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Used a technique similar to lavc/tdsc.c for invoking the MJPEG decoder.

This commit adds support for:
- DNG tiles
- DNG tile huffman lossless JPEG decoding
- DNG 8-bpp ("packed" as dcraw calls it) decoding
- DNG color scaling [1]
  - LinearizationTable tag
  - BlackLevel tag

[1]: As specified in the DNG Specification - Chapter 5

Signed-off-by: Nick Renieris 
---
 configure   |   1 +
 libavcodec/Makefile |   2 +-
 libavcodec/tiff.c   | 315 +++-
 libavcodec/tiff.h   |   2 +
 4 files changed, 312 insertions(+), 8 deletions(-)

diff --git a/configure b/configure
index 34c2adb4a4..112b84f0ba 100755
--- a/configure
+++ b/configure
@@ -2817,6 +2817,7 @@ tdsc_decoder_deps="zlib"
 tdsc_decoder_select="mjpeg_decoder"
 theora_decoder_select="vp3_decoder"
 thp_decoder_select="mjpeg_decoder"
+tiff_decoder_select="mjpeg_decoder"
 tiff_decoder_suggest="zlib lzma"
 tiff_encoder_suggest="zlib"
 truehd_decoder_select="mlp_parser"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3cd73fbcc6..f814c69996 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -616,7 +616,7 @@ OBJS-$(CONFIG_TARGA_ENCODER)   += targaenc.o rle.o
 OBJS-$(CONFIG_TARGA_Y216_DECODER)  += targa_y216dec.o
 OBJS-$(CONFIG_TDSC_DECODER)+= tdsc.o
 OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
-OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o 
tiff_common.o
+OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o 
tiff_common.o mjpegdec.o
 OBJS-$(CONFIG_TIFF_ENCODER)+= tiffenc.o rle.o lzwenc.o tiff_data.o
 OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o
 OBJS-$(CONFIG_TRUEHD_DECODER)  += mlpdec.o mlpdsp.o
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index c520d7df83..d5673abb19 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -35,6 +35,7 @@
 
 #include "libavutil/attributes.h"
 #include "libavutil/avstring.h"
+#include "libavutil/error.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
@@ -46,6 +47,7 @@
 #include "mathops.h"
 #include "tiff.h"
 #include "tiff_data.h"
+#include "mjpegdec.h"
 #include "thread.h"
 #include "get_bits.h"
 
@@ -54,6 +56,10 @@ typedef struct TiffContext {
 AVCodecContext *avctx;
 GetByteContext gb;
 
+/* JPEG decoding for DNG */
+AVCodecContext *avctx_mjpeg; // wrapper context for MJPEG
+AVFrame *jpgframe;   // decoded JPEG tile
+
 int get_subimage;
 uint16_t get_page;
 int get_thumbnail;
@@ -76,7 +82,9 @@ typedef struct TiffContext {
 
 int is_bayer;
 uint8_t pattern[4];
+unsigned black_level;
 unsigned white_level;
+const uint16_t *dng_lut; // Pointer to DNG linearization table
 
 uint32_t sub_ifd;
 uint16_t cur_page;
@@ -86,6 +94,14 @@ typedef struct TiffContext {
 int stripsizesoff, stripsize, stripoff, strippos;
 LZWState *lzw;
 
+/* Tile support */
+int is_tiled;
+int tile_byte_counts_offset, tile_offsets_offset;
+int tile_width, tile_length;
+int tile_count;
+
+int is_jpeg;
+
 uint8_t *deinvert_buf;
 int deinvert_buf_size;
 uint8_t *yuv_line;
@@ -257,6 +273,9 @@ static int add_metadata(int count, int type,
 };
 }
 
+static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
+  const uint8_t *src, int src_stride, int 
width, int height, int is_u16);
+
 static void av_always_inline horizontal_fill(TiffContext *s,
  unsigned int bpp, uint8_t* dst,
  int usePtr, const uint8_t *src,
@@ -712,6 +731,204 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 return 0;
 }
 
+/**
+ * Map stored raw sensor values into linear reference values.
+ * See: DNG Specification - Chapter 5
+ */
+static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
+const uint16_t *lut,
+uint16_t black_level,
+float scale_factor) {
+// Lookup table lookup
+if (lut)
+value = lut[value];
+
+// Black level subtraction
+value = av_clip_uint16_c((unsigned)value - black_level);
+
+// Color scaling
+value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
0x));
+
+return value;
+}
+
+static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+const uint16_t *lut,
+uint1

[FFmpeg-devel] [PATCH v12 03/14] lavc/tiff: Convert DNGs to sRGB color space

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 34 +++---
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index d5673abb19..a118c37c41 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -731,14 +731,23 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 return 0;
 }
 
+static float av_always_inline linear_to_srgb(float value) {
+if (value <= 0.0031308)
+return value * 12.92;
+else
+return pow(value * 1.055, 1.0 / 2.4) - 0.055;
+}
+
 /**
- * Map stored raw sensor values into linear reference values.
- * See: DNG Specification - Chapter 5
+ * Map stored raw sensor values into linear reference values (see: DNG 
Specification - Chapter 5)
+ * Then convert to sRGB color space.
  */
-static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
-const uint16_t *lut,
-uint16_t black_level,
-float scale_factor) {
+static uint16_t av_always_inline dng_process_color16(uint16_t value,
+ const uint16_t *lut,
+ uint16_t black_level,
+ float scale_factor) {
+float value_norm;
+
 // Lookup table lookup
 if (lut)
 value = lut[value];
@@ -747,16 +756,19 @@ static uint16_t av_always_inline 
dng_raw_to_linear16(uint16_t value,
 value = av_clip_uint16_c((unsigned)value - black_level);
 
 // Color scaling
-value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
0x));
+value_norm = (float)value * scale_factor;
+
+// Color space conversion (sRGB)
+value = av_clip_uint16_c((uint16_t)(linear_to_srgb(value_norm) * 0x));
 
 return value;
 }
 
-static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+static uint16_t av_always_inline dng_process_color8(uint16_t value,
 const uint16_t *lut,
 uint16_t black_level,
 float scale_factor) {
-return dng_raw_to_linear16(value, lut, black_level, scale_factor) >> 8;
+return dng_process_color16(value, lut, black_level, scale_factor) >> 8;
 }
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
@@ -774,7 +786,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 uint16_t *src_u16 = (uint16_t *)src;
 
 for (col = 0; col < width; col++)
-*dst_u16++ = dng_raw_to_linear16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
 
 dst += dst_stride * sizeof(uint16_t);
 src += src_stride * sizeof(uint16_t);
@@ -782,7 +794,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 } else {
 for (line = 0; line < height; line++) {
 for (col = 0; col < width; col++)
-*dst++ = dng_raw_to_linear8(*src++, s->dng_lut, 
s->black_level, scale_factor);
+*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
 
 dst += dst_stride;
 src += src_stride;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 09/14] lavc/mjpegdec: Enable decoding of single-component bayer images

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Also, ensure no false positives when determining DNG bayer images, by
setting them in tiff.c instead of relying on a heuristic.  There's no
way to determine this just from the JPEG data, so we have to pass this
information from outside the MJPEG decoder.

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 32 +---
 libavcodec/tiff.c |  7 +++
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 6391107f78..0a920a7144 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -412,13 +412,17 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 return AVERROR_PATCHWELCOME;
 }
 
-/* Lossless JPEGs encoded in DNGs are commonly bayer-encoded. They contain 
2
-   interleaved components and the width stored in their SOF3 markers is the
-   width of each one.  We only output a single component, therefore we need
-   to adjust the output image width. */
-if (s->lossless == 1 && nb_components == 2) {
-s->bayer = 1;
-width *= 2;
+if (s->bayer) {
+if (nb_components == 2) {
+/* Bayer images embedded in DNGs can contain 2 interleaved 
components and the
+   width stored in their SOF3 markers is the width of each one.  
We only output
+   a single component, therefore we need to adjust the output 
image width.  We
+   handle the deinterleaving (but not the debayering) in this 
file. */
+width *= 2;
+}
+/* They can also contain 1 component, which is double the width and 
half the height
+of the final image (rows are interleaved).  We don't handle the 
decoding in this
+file, but leave that to the TIFF/DNG decoder. */
 }
 
 /* if different size, realloc/alloc picture */
@@ -1184,10 +1188,16 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
 ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
 }
-} else if (s->bayer && nb_components == 2) {
-for (mb_x = 0; mb_x < width; mb_x++) {
-((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
-((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+} else if (s->bayer) {
+if (nb_components == 1) {
+/* Leave decoding to the TIFF/DNG decoder (see comment in 
ff_mjpeg_decode_sof) */
+for (mb_x = 0; mb_x < width; mb_x++)
+((uint16_t*)ptr)[mb_x] = buffer[mb_x][0];
+} else if (nb_components == 2) {
+for (mb_x = 0; mb_x < width; mb_x++) {
+((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
+((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+}
 }
 } else {
 for(i=0; igb.buffer;
 jpkt.size = tile_byte_count;
 
+if (s->is_bayer) {
+MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data;
+/* We have to set this information here, there is no way to know if a 
given JPEG is a DNG-embedded
+   image or not from its own data (and we need that information when 
decoding it). */
+mjpegdecctx->bayer = 1;
+}
+
 ret = avcodec_send_packet(s->avctx_mjpeg, &jpkt);
 if (ret < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for 
decoding\n");
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 04/14] lavc/tiff: Apply color scaling to uncompressed DNGs

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 25 -
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index a118c37c41..4620508d53 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -556,6 +556,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 int is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB) &&
  (desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
  desc->nb_components >= 3;
+int is_dng;
 
 if (s->planar)
 width /= s->bppcount;
@@ -657,6 +658,8 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 bytestream2_init(&s->gb, src, size);
 bytestream2_init_writer(&pb, dst, is_yuv ? s->yuv_line_size : (stride * 
lines));
 
+is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+
 for (line = 0; line < lines; line++) {
 if (src - ssrc > size) {
 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -679,6 +682,25 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 for (i = 0; i < width; i++)
 dst[i] = ff_reverse[src[i]];
 }
+
+/* Color processing for DNG images with uncompressed strips 
(non-tiled) */
+if (is_dng) {
+int is_u16, pixel_size_bytes, pixel_size_bits;
+
+is_u16 = (s->bpp > 8);
+pixel_size_bits = (is_u16 ? 16 : 8);
+pixel_size_bytes = (is_u16 ? sizeof(uint16_t) : 
sizeof(uint8_t));
+
+dng_blit(s,
+ dst,
+ 0, // no stride, only 1 line
+ dst,
+ 0, // no stride, only 1 line
+ width / pixel_size_bytes * pixel_size_bits / s->bpp, 
// need to account for [1, 16] bpp
+ 1,
+ is_u16);
+}
+
 src += width;
 break;
 case TIFF_PACKBITS:
@@ -1947,7 +1969,8 @@ again:
 FFSWAP(int,  p->linesize[0], p->linesize[1]);
 }
 
-if (s->is_bayer && s->white_level && s->bpp == 16) {
+if (s->is_bayer && s->white_level && s->bpp == 16 &&
+!(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)) {
 uint16_t *dst = (uint16_t *)p->data[0];
 for (i = 0; i < s->height; i++) {
 for (j = 0; j < s->width; j++)
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v12 13/14] lavc/tiff: Support DNGs with striped (non-tiled) JPEGs images

2019-08-09 Thread Nick Renieris
From: Nick Renieris 

DNG samples here can now be decoded:
- https://www.photographyblog.com/previews/pentax_k1_photos

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 73 +++
 1 file changed, 42 insertions(+), 31 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 0d931641c2..b9aa4efd02 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -550,6 +550,8 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, 
int stride,
 return ret;
 }
 
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame);
+
 static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int 
stride,
  const uint8_t *src, int size, int strip_start, 
int lines)
 {
@@ -665,6 +667,17 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 
 is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
 
+/* Decode JPEG-encoded DNGs with strips */
+if (s->compr == TIFF_NEWJPEG && is_dng) {
+if (s->strips > 1) {
+av_log(s->avctx, AV_LOG_ERROR, "More than one DNG JPEG strips 
unsupported\n");
+return AVERROR_PATCHWELCOME;
+}
+if ((ret = dng_decode_strip(s->avctx, p)) < 0)
+return ret;
+return 0;
+}
+
 for (line = 0; line < lines; line++) {
 if (src - ssrc > size) {
 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -859,8 +872,8 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 }
 }
 
-static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame,
-int tile_byte_count, int x, int y, int w, int 
h)
+static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame,
+   int tile_byte_count, int dst_x, int dst_y, int w, 
int h)
 {
 TiffContext *s = avctx->priv_data;
 AVPacket jpkt;
@@ -912,7 +925,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 return AVERROR_PATCHWELCOME;
 }
 
-dst_offset = x + frame->linesize[0] * y / pixel_size;
+dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size;
 dst_data = frame->data[0] + dst_offset * pixel_size;
 src_data = s->jpgframe->data[0];
 
@@ -931,7 +944,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 return 0;
 }
 
-static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame)
+static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, AVPacket 
*avpkt)
 {
 TiffContext *s = avctx->priv_data;
 int tile_idx;
@@ -944,6 +957,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame 
*frame)
 int pos_x = 0, pos_y = 0;
 int ret;
 
+s->jpgframe->width  = s->tile_width;
+s->jpgframe->height = s->tile_length;
+
+s->avctx_mjpeg->width = s->tile_width;
+s->avctx_mjpeg->height = s->tile_length;
+
 has_width_leftover = (s->width % s->tile_width != 0);
 has_height_leftover = (s->height % s->tile_length != 0);
 
@@ -980,7 +999,7 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame 
*frame)
 bytestream2_seek(&s->gb, tile_offset, SEEK_SET);
 
 /* Decode JPEG tile and copy it in the reference frame */
-ret = dng_decode_jpeg_tile(avctx, frame, tile_byte_count, pos_x, 
pos_y, tile_width, tile_length);
+ret = dng_decode_jpeg(avctx, frame, tile_byte_count, pos_x, pos_y, 
tile_width, tile_length);
 
 if (ret < 0)
 return ret;
@@ -993,30 +1012,24 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 }
 }
 
-return 0;
-}
+/* Frame is ready to be output */
+frame->pict_type = AV_PICTURE_TYPE_I;
+frame->key_frame = 1;
 
-static int dng_decode(AVCodecContext *avctx, AVFrame *frame, AVPacket *avpkt) {
-int ret;
+return avpkt->size;
+}
 
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame)
+{
 TiffContext *s = avctx->priv_data;
 
-s->jpgframe->width  = s->tile_width;
-s->jpgframe->height = s->tile_length;
-
-s->avctx_mjpeg->width = s->tile_width;
-s->avctx_mjpeg->height = s->tile_length;
-
-/* Decode all tiles in a frame */
-ret = dng_decode_tiles(avctx, frame);
-if (ret < 0)
-return ret;
+s->jpgframe->width  = s->width;
+s->jpgframe->height = s->height;
 
-/* Frame is ready to be output */
-frame->pict_type = AV_PICTURE_TYPE_I;
-frame->key_frame = 1;
+s->avctx_mjpeg->width = s->width;
+s->avctx_mjpeg->height = s->height;
 
-return avpkt->size;
+return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, 
s->height);
 }
 
 static int ini

Re: [FFmpeg-devel] [PATCH v12 03/14] lavc/tiff: Convert DNGs to sRGB color space

2019-08-10 Thread Nick Renieris
> Why do you put all this color space convertion code into the decoders ?

The color space conversion needs to happen, camera sensor data is
linear. If it's not done images looks really dark as result.

> Colorspace and pixel format convertion is generally done outside decoders.
> The specification cannot specify what part of FFmpeg's code does the
conversion.

I had found some sRGB conversion code in libswscale, asked about using
it and was told not to.
It's only 4 simple lines, as opposed to probably more complicated code
to use libswscale or whatever.

Στις Σάβ, 10 Αυγ 2019 στις 4:43 μ.μ., ο/η Nicolas George
 έγραψε:
>
> Paul B Mahol (12019-08-10):
> > It is part of DNG specification. Do you want to not follow DNG
> > specification?
>
> The specification cannot specify what part of FFmpeg's code does the
> conversion.
>
> --
>   Nicolas George
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v12 05/14] lavc/jpegtables: Handle multiple mappings to the same value

2019-08-10 Thread Nick Renieris
I haven't seen any files with sym!=0, just thought I'd solve the general case.
I'll change only for sym==0. Can always be changed later if any such
samples are found.


Στις Σάβ, 10 Αυγ 2019 στις 4:11 μ.μ., ο/η Michael Niedermayer
 έγραψε:
>
> On Fri, Aug 09, 2019 at 07:29:50PM +0300, Nick Renieris wrote:
> > From: Nick Renieris 
> >
> > Some JPEGs [1] have incorrect DHT entries that map 2 codes to
> > the same value.
> >
> > The second (last) mapping does not ever actually appear in the
> > code stream, therefore ignoring any mappings after the first one
> > fixes this.
> >
> > Without this, an "mjpeg_decode_dc: bad vlc: 0:0" error is thrown.
> >
> > ---
> >
> > [1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
> >  https://www.dji.com/gr/zenmuse-x7/info#downloads
> >
> > Signed-off-by: Nick Renieris 
> > ---
> >  libavcodec/jpegtables.c | 19 ---
> >  1 file changed, 16 insertions(+), 3 deletions(-)
> >
> > diff --git a/libavcodec/jpegtables.c b/libavcodec/jpegtables.c
> > index cbe5523cb4..6f596cfc92 100644
> > --- a/libavcodec/jpegtables.c
> > +++ b/libavcodec/jpegtables.c
> > @@ -130,14 +130,27 @@ void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, 
> > uint16_t *huff_code,
> >  {
> >  int i, j, k,nb, code, sym;
> >
> > -code = 0;
> > +/* Zero-initialize huff_size (needed for multiple mappings check 
> > below) */
> > +k = 0;
> > +for(i=1;i<=16;i++) {
> > +nb = bits_table[i];
> > +for(j=0;j > +sym = val_table[k++];
> > +huff_size[sym] = 0;
> > +}
> > +}
> > +
> >  k = 0;
> > +code = 0;
> >  for(i=1;i<=16;i++) {
> >  nb = bits_table[i];
> >  for(j=0;j >  sym = val_table[k++];
> > -huff_size[sym] = i;
> > -huff_code[sym] = code;
> > +/* If there are multiple mappings to the same sym (bad files), 
> > keep the first code */
> > +if (huff_size[sym] == 0) {
> > +huff_size[sym] = i;
> > +huff_code[sym] = code;
> > +}
>
> do these occur with sym different from 0 ?
> if its just 0 then this can be simplified alot
>
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> I do not agree with what you have to say, but I'll defend to the death your
> right to say it. -- Voltaire
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v12 12/14] lavc/mjpegdec: Skip useless APPx marker on bayer images

2019-08-10 Thread Nick Renieris
The data the marker contains is only 2 bytes and they're 0x in the
samples above. I don't know what they're for.


Στις Σάβ, 10 Αυγ 2019 στις 3:16 μ.μ., ο/η Michael Niedermayer
 έγραψε:
>
> On Fri, Aug 09, 2019 at 07:29:57PM +0300, Nick Renieris wrote:
> > From: Nick Renieris 
> >
> > Samples:
> > - Embedded JPEG images in the DNG images here:
> >   https://www.photographyblog.com/previews/pentax_k1_photos
> >
> > Signed-off-by: Nick Renieris 
> > ---
> >  libavcodec/mjpegdec.c | 11 +--
> >  1 file changed, 9 insertions(+), 2 deletions(-)
> >
> > diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
> > index 0a920a7144..e7b273a363 100644
> > --- a/libavcodec/mjpegdec.c
> > +++ b/libavcodec/mjpegdec.c
> > @@ -1807,8 +1807,15 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
> >  int len, id, i;
> >
> >  len = get_bits(&s->gb, 16);
> > -if (len < 6)
> > -return AVERROR_INVALIDDATA;
> > +if (len < 6) {
> > +if (s->bayer) {
> > +// Pentax K-1 (digital camera) JPEG images embedded in DNG 
> > images contain useless APP0 markers
>
> "useless" is a quite generic term, is it known what the contain why they
> are there ?
>
> thx
>
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> Asymptotically faster algorithms should always be preferred if you have
> asymptotical amounts of data
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v12 01/14] lavc/mjpegdec: Decode Huffman-coded lossless JPEGs embedded in DNGs

2019-08-10 Thread Nick Renieris
I assume you're talking about the "if (!s->bayer || mb_x) {"... code.

1) The special case there happens for the first line, not row like the
code you mentioned.
2) The loop is "width*height*component" in this order, so I'm not sure
how I would something for the first line outside.
3) It depends on mjpeg_decode_dc being called for the first-line case,
I'm not sure how I'd handle that either (even just to take it outside
the "component" loop).

Στις Σάβ, 10 Αυγ 2019 στις 3:30 μ.μ., ο/η Michael Niedermayer
 έγραψε:
>
> On Fri, Aug 09, 2019 at 07:29:46PM +0300, Nick Renieris wrote:
> > From: Nick Renieris 
> >
> > Main image data in DNGs is usually comprised of tiles, each of which is a 
> > Huffman-encoded lossless JPEG.
> >
> > Tested for ljpeg regressions with:
> > `ffmpeg -f lavfi -i testsrc=d=1 -vcodec ljpeg test.avi`
> > `ffmpeg test.avi out.avi`
> > The modified code in ljpeg_decode_rgb_scan runs without issues.
> >
> > Signed-off-by: Nick Renieris 
> > ---
> >  libavcodec/mjpegdec.c | 52 +--
> >  libavcodec/mjpegdec.h |  1 +
> >  2 files changed, 46 insertions(+), 7 deletions(-)
> [...]
>
> > @@ -1102,12 +1128,19 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext 
> > *s, int nb_components, int p
> >  topleft[i] = top[i];
> >  top[i] = buffer[mb_x][i];
> >
> > -PREDICT(pred, topleft[i], top[i], left[i], 
> > modified_predictor);
> > -
> >  dc = mjpeg_decode_dc(s, s->dc_index[i]);
> >  if(dc == 0xF)
> >  return -1;
> >
> > +if (!s->bayer || mb_x) {
> > +pred = left[i];
> > +} else { /* This path runs only for the first line in 
> > bayer images */
> > +vpred[i] += dc;
> > +pred = vpred[i] - dc;
> > +}
> > +
> > +PREDICT(pred, topleft[i], top[i], pred, 
> > modified_predictor);
> > +
> >  left[i] = buffer[mb_x][i] =
> >  mask & (pred + (unsigned)(dc * (1 << 
> > point_transform)));
> >  }
>
> This should be done outside the width*height sample loop
> The special handling of the left pixel for other ljpeg is also done
> outside that loop
>
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> What does censorship reveal? It reveals fear. -- Julian Assange
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v12 10/14] lavc/tiff: Support decoding of DNGs with single-component JPEGs

2019-08-10 Thread Nick Renieris
> after this commit the code dies when used with ffplay with floating point
> exceptions

I tried this on Ubuntu and I can't repro, it works fine.
Maybe something I changed locally fixed it, please re-test on the new
revision I'll send in a bit.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v13 01/14] lavc/mjpegdec: Decode Huffman-coded lossless JPEGs embedded in DNGs

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Main image data in DNGs is usually comprised of tiles, each of which is a 
Huffman-encoded lossless JPEG.

Tested for ljpeg regressions with:
`ffmpeg -f lavfi -i testsrc=d=1 -vcodec ljpeg test.avi`
`ffmpeg test.avi out.avi`
The modified code in ljpeg_decode_rgb_scan runs without issues.

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 52 +--
 libavcodec/mjpegdec.h |  1 +
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index a65bc8df15..6391107f78 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -412,6 +412,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 return AVERROR_PATCHWELCOME;
 }
 
+/* Lossless JPEGs encoded in DNGs are commonly bayer-encoded. They contain 
2
+   interleaved components and the width stored in their SOF3 markers is the
+   width of each one.  We only output a single component, therefore we need
+   to adjust the output image width. */
+if (s->lossless == 1 && nb_components == 2) {
+s->bayer = 1;
+width *= 2;
+}
 
 /* if different size, realloc/alloc picture */
 if (width != s->width || height != s->height || bits != s->bits ||
@@ -488,6 +496,9 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 }
 
 switch (pix_fmt_id) {
+case 0x: /* for bayer-encoded huffman lossless JPEGs embedded 
in DNGs */
+s->avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
+break;
 case 0x1100:
 if (s->rgb)
 s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_BGR24 : 
AV_PIX_FMT_BGR48;
@@ -1041,17 +1052,20 @@ static int handle_rstn(MJpegDecodeContext *s, int 
nb_components)
 return reset;
 }
 
+/* Handles 1 to 4 components */
 static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int 
predictor, int point_transform)
 {
 int i, mb_x, mb_y;
+unsigned width;
 uint16_t (*buffer)[4];
 int left[4], top[4], topleft[4];
 const int linesize = s->linesize[0];
 const int mask = ((1 << s->bits) - 1) << point_transform;
 int resync_mb_y = 0;
 int resync_mb_x = 0;
+int vpred[6];
 
-if (s->nb_components != 3 && s->nb_components != 4)
+if (s->nb_components <= 0 || s->nb_components > 4)
 return AVERROR_INVALIDDATA;
 if (s->v_max != 1 || s->h_max != 1 || !s->lossless)
 return AVERROR_INVALIDDATA;
@@ -1059,8 +1073,15 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 
 s->restart_count = s->restart_interval;
 
-av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size,
-   (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0]));
+if (s->restart_interval == 0)
+s->restart_interval = INT_MAX;
+
+if (s->bayer)
+width = s->mb_width / nb_components; /* Interleaved, width stored is 
the total so need to divide */
+else
+width = s->mb_width;
+
+av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, width * 4 * 
sizeof(s->ljpeg_buffer[0][0]));
 if (!s->ljpeg_buffer)
 return AVERROR(ENOMEM);
 
@@ -1078,7 +1099,12 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 for (i = 0; i < 4; i++)
 top[i] = left[i] = topleft[i] = buffer[0][i];
 
-for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+if ((mb_y * s->width) % s->restart_interval == 0) {
+for (i = 0; i < 6; i++)
+vpred[i] = 1 << (s->bits-1);
+}
+
+for (mb_x = 0; mb_x < width; mb_x++) {
 int modified_predictor = predictor;
 
 if (get_bits_left(&s->gb) < 1) {
@@ -1102,12 +1128,19 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 topleft[i] = top[i];
 top[i] = buffer[mb_x][i];
 
-PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
-
 dc = mjpeg_decode_dc(s, s->dc_index[i]);
 if(dc == 0xF)
 return -1;
 
+if (!s->bayer || mb_x) {
+pred = left[i];
+} else { /* This path runs only for the first line in bayer 
images */
+vpred[i] += dc;
+pred = vpred[i] - dc;
+}
+
+PREDICT(pred, topleft[i], top[i], pred, modified_predictor);
+
 left[i] = buffer[mb_x][i] =
 mask & (pred + (unsigned)(dc * (1 << point_transform)));
 }
@@ -1151,6 +1184,11 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 ptr[

[FFmpeg-devel] [PATCH v13 02/14] lavc/tiff: Decode embedded JPEGs in DNG images

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Used a technique similar to lavc/tdsc.c for invoking the MJPEG decoder.

This commit adds support for:
- DNG tiles
- DNG tile huffman lossless JPEG decoding
- DNG 8-bpp ("packed" as dcraw calls it) decoding
- DNG color scaling [1]
  - LinearizationTable tag
  - BlackLevel tag

[1]: As specified in the DNG Specification - Chapter 5

Signed-off-by: Nick Renieris 
---
 configure   |   1 +
 libavcodec/Makefile |   2 +-
 libavcodec/tiff.c   | 315 +++-
 libavcodec/tiff.h   |   2 +
 4 files changed, 312 insertions(+), 8 deletions(-)

diff --git a/configure b/configure
index 34c2adb4a4..112b84f0ba 100755
--- a/configure
+++ b/configure
@@ -2817,6 +2817,7 @@ tdsc_decoder_deps="zlib"
 tdsc_decoder_select="mjpeg_decoder"
 theora_decoder_select="vp3_decoder"
 thp_decoder_select="mjpeg_decoder"
+tiff_decoder_select="mjpeg_decoder"
 tiff_decoder_suggest="zlib lzma"
 tiff_encoder_suggest="zlib"
 truehd_decoder_select="mlp_parser"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3cd73fbcc6..f814c69996 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -616,7 +616,7 @@ OBJS-$(CONFIG_TARGA_ENCODER)   += targaenc.o rle.o
 OBJS-$(CONFIG_TARGA_Y216_DECODER)  += targa_y216dec.o
 OBJS-$(CONFIG_TDSC_DECODER)+= tdsc.o
 OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
-OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o 
tiff_common.o
+OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o 
tiff_common.o mjpegdec.o
 OBJS-$(CONFIG_TIFF_ENCODER)+= tiffenc.o rle.o lzwenc.o tiff_data.o
 OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o
 OBJS-$(CONFIG_TRUEHD_DECODER)  += mlpdec.o mlpdsp.o
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index c520d7df83..d5673abb19 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -35,6 +35,7 @@
 
 #include "libavutil/attributes.h"
 #include "libavutil/avstring.h"
+#include "libavutil/error.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
@@ -46,6 +47,7 @@
 #include "mathops.h"
 #include "tiff.h"
 #include "tiff_data.h"
+#include "mjpegdec.h"
 #include "thread.h"
 #include "get_bits.h"
 
@@ -54,6 +56,10 @@ typedef struct TiffContext {
 AVCodecContext *avctx;
 GetByteContext gb;
 
+/* JPEG decoding for DNG */
+AVCodecContext *avctx_mjpeg; // wrapper context for MJPEG
+AVFrame *jpgframe;   // decoded JPEG tile
+
 int get_subimage;
 uint16_t get_page;
 int get_thumbnail;
@@ -76,7 +82,9 @@ typedef struct TiffContext {
 
 int is_bayer;
 uint8_t pattern[4];
+unsigned black_level;
 unsigned white_level;
+const uint16_t *dng_lut; // Pointer to DNG linearization table
 
 uint32_t sub_ifd;
 uint16_t cur_page;
@@ -86,6 +94,14 @@ typedef struct TiffContext {
 int stripsizesoff, stripsize, stripoff, strippos;
 LZWState *lzw;
 
+/* Tile support */
+int is_tiled;
+int tile_byte_counts_offset, tile_offsets_offset;
+int tile_width, tile_length;
+int tile_count;
+
+int is_jpeg;
+
 uint8_t *deinvert_buf;
 int deinvert_buf_size;
 uint8_t *yuv_line;
@@ -257,6 +273,9 @@ static int add_metadata(int count, int type,
 };
 }
 
+static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
+  const uint8_t *src, int src_stride, int 
width, int height, int is_u16);
+
 static void av_always_inline horizontal_fill(TiffContext *s,
  unsigned int bpp, uint8_t* dst,
  int usePtr, const uint8_t *src,
@@ -712,6 +731,204 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 return 0;
 }
 
+/**
+ * Map stored raw sensor values into linear reference values.
+ * See: DNG Specification - Chapter 5
+ */
+static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
+const uint16_t *lut,
+uint16_t black_level,
+float scale_factor) {
+// Lookup table lookup
+if (lut)
+value = lut[value];
+
+// Black level subtraction
+value = av_clip_uint16_c((unsigned)value - black_level);
+
+// Color scaling
+value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
0x));
+
+return value;
+}
+
+static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+const uint16_t *lut,
+uint1

[FFmpeg-devel] [PATCH v13 03/14] lavc/tiff: Convert DNGs to sRGB color space

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 34 +++---
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index d5673abb19..a118c37c41 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -731,14 +731,23 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 return 0;
 }
 
+static float av_always_inline linear_to_srgb(float value) {
+if (value <= 0.0031308)
+return value * 12.92;
+else
+return pow(value * 1.055, 1.0 / 2.4) - 0.055;
+}
+
 /**
- * Map stored raw sensor values into linear reference values.
- * See: DNG Specification - Chapter 5
+ * Map stored raw sensor values into linear reference values (see: DNG 
Specification - Chapter 5)
+ * Then convert to sRGB color space.
  */
-static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
-const uint16_t *lut,
-uint16_t black_level,
-float scale_factor) {
+static uint16_t av_always_inline dng_process_color16(uint16_t value,
+ const uint16_t *lut,
+ uint16_t black_level,
+ float scale_factor) {
+float value_norm;
+
 // Lookup table lookup
 if (lut)
 value = lut[value];
@@ -747,16 +756,19 @@ static uint16_t av_always_inline 
dng_raw_to_linear16(uint16_t value,
 value = av_clip_uint16_c((unsigned)value - black_level);
 
 // Color scaling
-value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
0x));
+value_norm = (float)value * scale_factor;
+
+// Color space conversion (sRGB)
+value = av_clip_uint16_c((uint16_t)(linear_to_srgb(value_norm) * 0x));
 
 return value;
 }
 
-static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+static uint16_t av_always_inline dng_process_color8(uint16_t value,
 const uint16_t *lut,
 uint16_t black_level,
 float scale_factor) {
-return dng_raw_to_linear16(value, lut, black_level, scale_factor) >> 8;
+return dng_process_color16(value, lut, black_level, scale_factor) >> 8;
 }
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
@@ -774,7 +786,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 uint16_t *src_u16 = (uint16_t *)src;
 
 for (col = 0; col < width; col++)
-*dst_u16++ = dng_raw_to_linear16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
 
 dst += dst_stride * sizeof(uint16_t);
 src += src_stride * sizeof(uint16_t);
@@ -782,7 +794,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 } else {
 for (line = 0; line < height; line++) {
 for (col = 0; col < width; col++)
-*dst++ = dng_raw_to_linear8(*src++, s->dng_lut, 
s->black_level, scale_factor);
+*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
 
 dst += dst_stride;
 src += src_stride;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v13 05/14] lavc/jpegtables: Handle multiple mappings to the same value

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Some JPEGs [1] have incorrect DHT entries that map 2 codes to
the same value.

The second (last) mapping does not ever actually appear in the
code stream, therefore ignoring any mappings after the first one
fixes this.

Without this, an "mjpeg_decode_dc: bad vlc: 0:0" error is thrown.

In all known files, the 2 codes are mapped to symbol 0 so only
that case is checked.

---

[1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
 https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/jpegtables.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/libavcodec/jpegtables.c b/libavcodec/jpegtables.c
index cbe5523cb4..fa5c6f9fc5 100644
--- a/libavcodec/jpegtables.c
+++ b/libavcodec/jpegtables.c
@@ -130,14 +130,25 @@ void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, 
uint16_t *huff_code,
 {
 int i, j, k,nb, code, sym;
 
-code = 0;
+/* Some badly encoded files [1] map 2 different codes to symbol 0.
+   Only the first one is valid, so we zero-initialize this here and
+   make sure we only set it once (the first time) in the loop below.
+
+   [1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
+https://www.dji.com/gr/zenmuse-x7/info#downloads
+ */
+huff_size[0] = 0;
+
 k = 0;
+code = 0;
 for(i=1;i<=16;i++) {
 nb = bits_table[i];
 for(j=0;jhttps://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v13 04/14] lavc/tiff: Apply color scaling to uncompressed DNGs

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 25 -
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index a118c37c41..4620508d53 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -556,6 +556,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 int is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB) &&
  (desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
  desc->nb_components >= 3;
+int is_dng;
 
 if (s->planar)
 width /= s->bppcount;
@@ -657,6 +658,8 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 bytestream2_init(&s->gb, src, size);
 bytestream2_init_writer(&pb, dst, is_yuv ? s->yuv_line_size : (stride * 
lines));
 
+is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+
 for (line = 0; line < lines; line++) {
 if (src - ssrc > size) {
 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -679,6 +682,25 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 for (i = 0; i < width; i++)
 dst[i] = ff_reverse[src[i]];
 }
+
+/* Color processing for DNG images with uncompressed strips 
(non-tiled) */
+if (is_dng) {
+int is_u16, pixel_size_bytes, pixel_size_bits;
+
+is_u16 = (s->bpp > 8);
+pixel_size_bits = (is_u16 ? 16 : 8);
+pixel_size_bytes = (is_u16 ? sizeof(uint16_t) : 
sizeof(uint8_t));
+
+dng_blit(s,
+ dst,
+ 0, // no stride, only 1 line
+ dst,
+ 0, // no stride, only 1 line
+ width / pixel_size_bytes * pixel_size_bits / s->bpp, 
// need to account for [1, 16] bpp
+ 1,
+ is_u16);
+}
+
 src += width;
 break;
 case TIFF_PACKBITS:
@@ -1947,7 +1969,8 @@ again:
 FFSWAP(int,  p->linesize[0], p->linesize[1]);
 }
 
-if (s->is_bayer && s->white_level && s->bpp == 16) {
+if (s->is_bayer && s->white_level && s->bpp == 16 &&
+!(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)) {
 uint16_t *dst = (uint16_t *)p->data[0];
 for (i = 0; i < s->height; i++) {
 for (j = 0; j < s->width; j++)
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v13 06/14] lavc/tiff: Fix edge case with full-length/width tiles

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

In an image [1], the height was equal to the tile length (full-height
tile) and after `height % tile_length` was applied to them with the
current code, it resulted in the operating tile_length to be 0.  This
commit makes this leftover logic only applies if it's necessary.

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 4620508d53..37fda15162 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -887,10 +887,14 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 int tile_byte_count_offset, tile_byte_count;
 int tile_count_x, tile_count_y;
 int tile_width, tile_length;
+int has_width_leftover, has_height_leftover;
 int tile_x = 0, tile_y = 0;
 int pos_x = 0, pos_y = 0;
 int ret;
 
+has_width_leftover = (s->width % s->tile_width != 0);
+has_height_leftover = (s->height % s->tile_length != 0);
+
 /* Calculate tile counts (round up) */
 tile_count_x = (s->width + s->tile_width - 1) / s->tile_width;
 tile_count_y = (s->height + s->tile_length - 1) / s->tile_length;
@@ -900,12 +904,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 tile_x = tile_idx % tile_count_x;
 tile_y = tile_idx / tile_count_x;
 
-if (tile_x == tile_count_x - 1) // If on the right edge
+if (has_width_leftover && tile_x == tile_count_x - 1) // If on the 
right-most tile
 tile_width = s->width % s->tile_width;
 else
 tile_width = s->tile_width;
 
-if (tile_y == tile_count_y - 1) // If on the bottom edge
+if (has_height_leftover && tile_y == tile_count_y - 1) // If on the 
bottom-most tile
 tile_length = s->height % s->tile_length;
 else
 tile_length = s->tile_length;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v13 10/14] lavc/tiff: Support decoding of DNGs with single-component JPEGs

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

This enables decoding of DNG images generated by the 'DJI Zenmuse X7'
digital camera
Samples: https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 61 +++
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index cf8965453c..ecd87c0b2f 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -274,7 +274,8 @@ static int add_metadata(int count, int type,
 }
 
 static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
-  const uint8_t *src, int src_stride, int 
width, int height, int is_u16);
+  const uint8_t *src, int src_stride, int 
width, int height,
+  int is_single_comp, int is_u16);
 
 static void av_always_inline horizontal_fill(TiffContext *s,
  unsigned int bpp, uint8_t* dst,
@@ -698,6 +699,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
  0, // no stride, only 1 line
  width / pixel_size_bytes * pixel_size_bits / s->bpp, 
// need to account for [1, 16] bpp
  1,
+ 0, // single-component variation is only preset in 
JPEG-encoded DNGs
  is_u16);
 }
 
@@ -795,18 +797,32 @@ static uint16_t av_always_inline 
dng_process_color8(uint16_t value,
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
  const uint8_t *src, int src_stride,
- int width, int height, int is_u16)
+ int width, int height, int is_single_comp, int is_u16)
 {
 int line, col;
 float scale_factor;
 
 scale_factor = 1.0f / (s->white_level - s->black_level);
 
-if (is_u16) {
-for (line = 0; line < height; line++) {
+if (is_single_comp) {
+if (!is_u16)
+return; /* <= 8bpp unsupported */
+
+/* Image is double the width and half the height we need, each row 
comprises 2 rows of the output
+   (split vertically in the middle). */
+for (line = 0; line < height / 2; line++) {
 uint16_t *dst_u16 = (uint16_t *)dst;
 uint16_t *src_u16 = (uint16_t *)src;
 
+/* Blit first half of input row row to initial row of output */
+for (col = 0; col < width; col++)
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+
+/* Advance the destination pointer by a row (source pointer 
remains in the same place) */
+dst += dst_stride * sizeof(uint16_t);
+dst_u16 = (uint16_t *)dst;
+
+/* Blit second half of input row row to next row of output */
 for (col = 0; col < width; col++)
 *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
 
@@ -814,12 +830,27 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 src += src_stride * sizeof(uint16_t);
 }
 } else {
-for (line = 0; line < height; line++) {
-for (col = 0; col < width; col++)
-*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
+/* Input and output image are the same size and the MJpeg decoder has 
done per-component
+   deinterleaving, so blitting here is straightforward. */
+if (is_u16) {
+for (line = 0; line < height; line++) {
+uint16_t *dst_u16 = (uint16_t *)dst;
+uint16_t *src_u16 = (uint16_t *)src;
+
+for (col = 0; col < width; col++)
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+
+dst += dst_stride * sizeof(uint16_t);
+src += src_stride * sizeof(uint16_t);
+}
+} else {
+for (line = 0; line < height; line++) {
+for (col = 0; col < width; col++)
+*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
 
-dst += dst_stride;
-src += src_stride;
+dst += dst_stride;
+src += src_stride;
+}
 }
 }
 }
@@ -831,7 +862,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 AVPacket jpkt;
 uint8_t *dst_data, *src_data;
 uint32_t dst_offset; /* offset from dst buffer in pixels */
-int is_u16, pixel_size;
+int is_single_comp, is_u16, pixel_size;
 int ret;
 
 /* Prepare a packet and send to the MJPEG decoder */
@@ -865,9 +896,18 @@ static int dng_decode_jpeg_tile(AVCod

[FFmpeg-devel] [PATCH v13 07/14] lavc/tiff: Don't apply strips-related logic to tiled images

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 42 ++
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 37fda15162..174ca168c6 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1780,7 +1780,7 @@ again:
 }
 }
 
-if (!s->strippos && !s->stripoff) {
+if (!s->is_tiled && !s->strippos && !s->stripoff) {
 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
 return AVERROR_INVALIDDATA;
 }
@@ -1788,27 +1788,29 @@ again:
 if ((ret = init_image(s, &frame)) < 0)
 return ret;
 
-if (s->strips == 1 && !s->stripsize) {
-av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
-s->stripsize = avpkt->size - s->stripoff;
-}
+if (!s->is_tiled) {
+if (s->strips == 1 && !s->stripsize) {
+av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
+s->stripsize = avpkt->size - s->stripoff;
+}
 
-if (s->stripsizesoff) {
-if (s->stripsizesoff >= (unsigned)avpkt->size)
-return AVERROR_INVALIDDATA;
-bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
- avpkt->size - s->stripsizesoff);
-}
-if (s->strippos) {
-if (s->strippos >= (unsigned)avpkt->size)
-return AVERROR_INVALIDDATA;
-bytestream2_init(&stripdata, avpkt->data + s->strippos,
- avpkt->size - s->strippos);
-}
+if (s->stripsizesoff) {
+if (s->stripsizesoff >= (unsigned)avpkt->size)
+return AVERROR_INVALIDDATA;
+bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
+avpkt->size - s->stripsizesoff);
+}
+if (s->strippos) {
+if (s->strippos >= (unsigned)avpkt->size)
+return AVERROR_INVALIDDATA;
+bytestream2_init(&stripdata, avpkt->data + s->strippos,
+avpkt->size - s->strippos);
+}
 
-if (s->rps <= 0 || s->rps % s->subsampling[1]) {
-av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
-return AVERROR_INVALIDDATA;
+if (s->rps <= 0 || s->rps % s->subsampling[1]) {
+av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
+return AVERROR_INVALIDDATA;
+}
 }
 
 /* Handle DNG images with JPEG-compressed tiles */
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v13 09/14] lavc/mjpegdec: Enable decoding of single-component bayer images

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Also, ensure no false positives when determining DNG bayer images, by
setting them in tiff.c instead of relying on a heuristic.  There's no
way to determine this just from the JPEG data, so we have to pass this
information from outside the MJPEG decoder.

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 32 +---
 libavcodec/tiff.c |  7 +++
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 6391107f78..0a920a7144 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -412,13 +412,17 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 return AVERROR_PATCHWELCOME;
 }
 
-/* Lossless JPEGs encoded in DNGs are commonly bayer-encoded. They contain 
2
-   interleaved components and the width stored in their SOF3 markers is the
-   width of each one.  We only output a single component, therefore we need
-   to adjust the output image width. */
-if (s->lossless == 1 && nb_components == 2) {
-s->bayer = 1;
-width *= 2;
+if (s->bayer) {
+if (nb_components == 2) {
+/* Bayer images embedded in DNGs can contain 2 interleaved 
components and the
+   width stored in their SOF3 markers is the width of each one.  
We only output
+   a single component, therefore we need to adjust the output 
image width.  We
+   handle the deinterleaving (but not the debayering) in this 
file. */
+width *= 2;
+}
+/* They can also contain 1 component, which is double the width and 
half the height
+of the final image (rows are interleaved).  We don't handle the 
decoding in this
+file, but leave that to the TIFF/DNG decoder. */
 }
 
 /* if different size, realloc/alloc picture */
@@ -1184,10 +1188,16 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
 ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
 }
-} else if (s->bayer && nb_components == 2) {
-for (mb_x = 0; mb_x < width; mb_x++) {
-((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
-((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+} else if (s->bayer) {
+if (nb_components == 1) {
+/* Leave decoding to the TIFF/DNG decoder (see comment in 
ff_mjpeg_decode_sof) */
+for (mb_x = 0; mb_x < width; mb_x++)
+((uint16_t*)ptr)[mb_x] = buffer[mb_x][0];
+} else if (nb_components == 2) {
+for (mb_x = 0; mb_x < width; mb_x++) {
+((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
+((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+}
 }
 } else {
 for(i=0; igb.buffer;
 jpkt.size = tile_byte_count;
 
+if (s->is_bayer) {
+MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data;
+/* We have to set this information here, there is no way to know if a 
given JPEG is a DNG-embedded
+   image or not from its own data (and we need that information when 
decoding it). */
+mjpegdecctx->bayer = 1;
+}
+
 ret = avcodec_send_packet(s->avctx_mjpeg, &jpkt);
 if (ret < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for 
decoding\n");
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v13 08/14] lavc/tiff: Force DNG pixel data endianness on an edge case

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 174ca168c6..9d20763186 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1038,6 +1038,18 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
AV_RL32(s->pattern));
 return AVERROR_PATCHWELCOME;
 }
+/* Force endianness as mentioned in 'DNG Specification: Chapter 3: 
BitsPerSample'
+NOTE: The spec actually specifies big-endian, not sure why we need 
little-endian,
+  but such images don't work otherwise. */
+if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)
+&& (s->bpp != 8 && s->bpp != 16 && s->bpp != 32)) {
+switch (s->avctx->pix_fmt) {
+case AV_PIX_FMT_BAYER_RGGB16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_RGGB16LE; break;
+case AV_PIX_FMT_BAYER_BGGR16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_BGGR16LE; break;
+case AV_PIX_FMT_BAYER_GBRG16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_GBRG16LE; break;
+case AV_PIX_FMT_BAYER_GRBG16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_GRBG16LE; break;
+}
+}
 break;
 case 10161:
 switch (AV_RL32(s->pattern)) {
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v13 13/14] lavc/tiff: Support DNGs with striped (non-tiled) JPEGs images

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

DNG samples here can now be decoded:
- https://www.photographyblog.com/previews/pentax_k1_photos

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 73 +++
 1 file changed, 42 insertions(+), 31 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 0d931641c2..b9aa4efd02 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -550,6 +550,8 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, 
int stride,
 return ret;
 }
 
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame);
+
 static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int 
stride,
  const uint8_t *src, int size, int strip_start, 
int lines)
 {
@@ -665,6 +667,17 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 
 is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
 
+/* Decode JPEG-encoded DNGs with strips */
+if (s->compr == TIFF_NEWJPEG && is_dng) {
+if (s->strips > 1) {
+av_log(s->avctx, AV_LOG_ERROR, "More than one DNG JPEG strips 
unsupported\n");
+return AVERROR_PATCHWELCOME;
+}
+if ((ret = dng_decode_strip(s->avctx, p)) < 0)
+return ret;
+return 0;
+}
+
 for (line = 0; line < lines; line++) {
 if (src - ssrc > size) {
 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -859,8 +872,8 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 }
 }
 
-static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame,
-int tile_byte_count, int x, int y, int w, int 
h)
+static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame,
+   int tile_byte_count, int dst_x, int dst_y, int w, 
int h)
 {
 TiffContext *s = avctx->priv_data;
 AVPacket jpkt;
@@ -912,7 +925,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 return AVERROR_PATCHWELCOME;
 }
 
-dst_offset = x + frame->linesize[0] * y / pixel_size;
+dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size;
 dst_data = frame->data[0] + dst_offset * pixel_size;
 src_data = s->jpgframe->data[0];
 
@@ -931,7 +944,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 return 0;
 }
 
-static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame)
+static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, AVPacket 
*avpkt)
 {
 TiffContext *s = avctx->priv_data;
 int tile_idx;
@@ -944,6 +957,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame 
*frame)
 int pos_x = 0, pos_y = 0;
 int ret;
 
+s->jpgframe->width  = s->tile_width;
+s->jpgframe->height = s->tile_length;
+
+s->avctx_mjpeg->width = s->tile_width;
+s->avctx_mjpeg->height = s->tile_length;
+
 has_width_leftover = (s->width % s->tile_width != 0);
 has_height_leftover = (s->height % s->tile_length != 0);
 
@@ -980,7 +999,7 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame 
*frame)
 bytestream2_seek(&s->gb, tile_offset, SEEK_SET);
 
 /* Decode JPEG tile and copy it in the reference frame */
-ret = dng_decode_jpeg_tile(avctx, frame, tile_byte_count, pos_x, 
pos_y, tile_width, tile_length);
+ret = dng_decode_jpeg(avctx, frame, tile_byte_count, pos_x, pos_y, 
tile_width, tile_length);
 
 if (ret < 0)
 return ret;
@@ -993,30 +1012,24 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 }
 }
 
-return 0;
-}
+/* Frame is ready to be output */
+frame->pict_type = AV_PICTURE_TYPE_I;
+frame->key_frame = 1;
 
-static int dng_decode(AVCodecContext *avctx, AVFrame *frame, AVPacket *avpkt) {
-int ret;
+return avpkt->size;
+}
 
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame)
+{
 TiffContext *s = avctx->priv_data;
 
-s->jpgframe->width  = s->tile_width;
-s->jpgframe->height = s->tile_length;
-
-s->avctx_mjpeg->width = s->tile_width;
-s->avctx_mjpeg->height = s->tile_length;
-
-/* Decode all tiles in a frame */
-ret = dng_decode_tiles(avctx, frame);
-if (ret < 0)
-return ret;
+s->jpgframe->width  = s->width;
+s->jpgframe->height = s->height;
 
-/* Frame is ready to be output */
-frame->pict_type = AV_PICTURE_TYPE_I;
-frame->key_frame = 1;
+s->avctx_mjpeg->width = s->width;
+s->avctx_mjpeg->height = s->height;
 
-return avpkt->size;
+return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, 
s->height);
 }
 
 static int ini

[FFmpeg-devel] [PATCH v13 12/14] lavc/mjpegdec: Skip unknown APPx marker on bayer images

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Samples:
- Embedded JPEG images in the DNG images here:
  https://www.photographyblog.com/previews/pentax_k1_photos

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 0a920a7144..1f2fabe2df 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1807,8 +1807,15 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
 int len, id, i;
 
 len = get_bits(&s->gb, 16);
-if (len < 6)
-return AVERROR_INVALIDDATA;
+if (len < 6) {
+if (s->bayer) {
+// Pentax K-1 (digital camera) JPEG images embedded in DNG images 
contain unknown APP0 markers
+av_log(s->avctx, AV_LOG_WARNING, "skipping APPx (len=%"PRId32") 
for bayer-encoded image\n", len);
+skip_bits(&s->gb, len);
+return 0;
+} else
+return AVERROR_INVALIDDATA;
+}
 if (8 * len > get_bits_left(&s->gb))
 return AVERROR_INVALIDDATA;
 
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v13 11/14] lavc/tiff: Decode 14-bit DNG images

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Sample file: 
https://drive.google.com/open?id=0B4JyRT3Lth5HVndyOTVOdWktM3J4TFEydTk1MnY3RWlpSzVB

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index ecd87c0b2f..0d931641c2 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -309,14 +309,18 @@ static void av_always_inline horizontal_fill(TiffContext 
*s,
 dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4;
 }
 break;
-case 12: {
- uint16_t *dst16 = (uint16_t *)dst;
- GetBitContext gb;
- init_get_bits8(&gb, src, width);
- for (int i = 0; i < s->width; i++) {
- dst16[i] = get_bits(&gb, 12) << 4;
- }
- }
+case 12:
+case 14: {
+uint16_t *dst16 = (uint16_t *)dst;
+int is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+uint8_t shift = is_dng ? 0 : 16 - bpp;
+GetBitContext gb;
+
+init_get_bits8(&gb, src, width);
+for (int i = 0; i < s->width; i++) {
+dst16[i] = get_bits(&gb, bpp) << shift;
+}
+}
 break;
 default:
 if (usePtr) {
@@ -1068,6 +1072,7 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
 }
 break;
 case 10121:
+case 10141:
 switch (AV_RL32(s->pattern)) {
 case 0x02010100:
 s->avctx->pix_fmt = s->le ? AV_PIX_FMT_BAYER_RGGB16LE : 
AV_PIX_FMT_BAYER_RGGB16BE;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v13 14/14] lavc/tiff: Default-initialize WhiteLevel DNG tag value

2019-08-10 Thread Nick Renieris
From: Nick Renieris 

Initialized to `(2 ^ BitsPerSample) - 1` as per the DNG Specification.

Also make sure that `BlackLevel < WhiteLevel`.

This fixes decoding for "X7 CinemaDNG" samples here:
- https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index b9aa4efd02..b985f19fe2 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1773,6 +1773,7 @@ static int decode_frame(AVCodecContext *avctx,
 GetByteContext stripsizes;
 GetByteContext stripdata;
 int retry_for_subifd, retry_for_page;
+int is_dng;
 
 bytestream2_init(&s->gb, avpkt->data, avpkt->size);
 
@@ -1841,6 +1842,10 @@ again:
 goto again;
 }
 
+/* At this point we've decided on which (Sub)IFD to process */
+
+is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+
 for (i = 0; igeotag_count; i++) {
 const char *keyname = get_geokey_name(s->geotags[i].key);
 if (!keyname) {
@@ -1858,10 +1863,20 @@ again:
 }
 }
 
+if (s->white_level == 0)
+s->white_level = (1 << s->bpp) - 1; /* Default value as per the spec */
+
+if (s->white_level <= s->black_level) {
+av_log(avctx, AV_LOG_ERROR, "BlackLevel (%"PRId32") must be less than 
WhiteLevel (%"PRId32")\n",
+   s->black_level, s->white_level);
+return AVERROR_INVALIDDATA;
+}
+
 if (!s->is_tiled && !s->strippos && !s->stripoff) {
 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
 return AVERROR_INVALIDDATA;
 }
+
 /* now we have the data and may start decoding */
 if ((ret = init_image(s, &frame)) < 0)
 return ret;
@@ -1893,7 +1908,7 @@ again:
 
 /* Handle DNG images with JPEG-compressed tiles */
 
-if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG) 
&& s->is_tiled) {
+if (is_dng && s->is_tiled) {
 if (!s->is_jpeg) {
 avpriv_report_missing_feature(avctx, "DNG uncompressed tiled 
images");
 return AVERROR_PATCHWELCOME;
@@ -2051,8 +2066,7 @@ again:
 FFSWAP(int,  p->linesize[0], p->linesize[1]);
 }
 
-if (s->is_bayer && s->white_level && s->bpp == 16 &&
-!(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)) {
+if (s->is_bayer && s->bpp == 16 && !is_dng && (s->white_level != (1 << 
s->bpp) - 1)) {
 uint16_t *dst = (uint16_t *)p->data[0];
 for (i = 0; i < s->height; i++) {
 for (j = 0; j < s->width; j++)
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 01/14] lavc/mjpegdec: Decode Huffman-coded lossless JPEGs embedded in DNGs

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Main image data in DNGs is usually comprised of tiles, each of which is a 
Huffman-encoded lossless JPEG.

Tested for ljpeg regressions with:
`ffmpeg -f lavfi -i testsrc=d=1 -vcodec ljpeg test.avi`
`ffmpeg test.avi out.avi`
The modified code in ljpeg_decode_rgb_scan runs without issues.

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 52 +--
 libavcodec/mjpegdec.h |  1 +
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index a65bc8df15..6391107f78 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -412,6 +412,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 return AVERROR_PATCHWELCOME;
 }
 
+/* Lossless JPEGs encoded in DNGs are commonly bayer-encoded. They contain 
2
+   interleaved components and the width stored in their SOF3 markers is the
+   width of each one.  We only output a single component, therefore we need
+   to adjust the output image width. */
+if (s->lossless == 1 && nb_components == 2) {
+s->bayer = 1;
+width *= 2;
+}
 
 /* if different size, realloc/alloc picture */
 if (width != s->width || height != s->height || bits != s->bits ||
@@ -488,6 +496,9 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 }
 
 switch (pix_fmt_id) {
+case 0x: /* for bayer-encoded huffman lossless JPEGs embedded 
in DNGs */
+s->avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
+break;
 case 0x1100:
 if (s->rgb)
 s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_BGR24 : 
AV_PIX_FMT_BGR48;
@@ -1041,17 +1052,20 @@ static int handle_rstn(MJpegDecodeContext *s, int 
nb_components)
 return reset;
 }
 
+/* Handles 1 to 4 components */
 static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int 
predictor, int point_transform)
 {
 int i, mb_x, mb_y;
+unsigned width;
 uint16_t (*buffer)[4];
 int left[4], top[4], topleft[4];
 const int linesize = s->linesize[0];
 const int mask = ((1 << s->bits) - 1) << point_transform;
 int resync_mb_y = 0;
 int resync_mb_x = 0;
+int vpred[6];
 
-if (s->nb_components != 3 && s->nb_components != 4)
+if (s->nb_components <= 0 || s->nb_components > 4)
 return AVERROR_INVALIDDATA;
 if (s->v_max != 1 || s->h_max != 1 || !s->lossless)
 return AVERROR_INVALIDDATA;
@@ -1059,8 +1073,15 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 
 s->restart_count = s->restart_interval;
 
-av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size,
-   (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0]));
+if (s->restart_interval == 0)
+s->restart_interval = INT_MAX;
+
+if (s->bayer)
+width = s->mb_width / nb_components; /* Interleaved, width stored is 
the total so need to divide */
+else
+width = s->mb_width;
+
+av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, width * 4 * 
sizeof(s->ljpeg_buffer[0][0]));
 if (!s->ljpeg_buffer)
 return AVERROR(ENOMEM);
 
@@ -1078,7 +1099,12 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 for (i = 0; i < 4; i++)
 top[i] = left[i] = topleft[i] = buffer[0][i];
 
-for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+if ((mb_y * s->width) % s->restart_interval == 0) {
+for (i = 0; i < 6; i++)
+vpred[i] = 1 << (s->bits-1);
+}
+
+for (mb_x = 0; mb_x < width; mb_x++) {
 int modified_predictor = predictor;
 
 if (get_bits_left(&s->gb) < 1) {
@@ -1102,12 +1128,19 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 topleft[i] = top[i];
 top[i] = buffer[mb_x][i];
 
-PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
-
 dc = mjpeg_decode_dc(s, s->dc_index[i]);
 if(dc == 0xF)
 return -1;
 
+if (!s->bayer || mb_x) {
+pred = left[i];
+} else { /* This path runs only for the first line in bayer 
images */
+vpred[i] += dc;
+pred = vpred[i] - dc;
+}
+
+PREDICT(pred, topleft[i], top[i], pred, modified_predictor);
+
 left[i] = buffer[mb_x][i] =
 mask & (pred + (unsigned)(dc * (1 << point_transform)));
 }
@@ -1151,6 +1184,11 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 ptr[

[FFmpeg-devel] [PATCH v14 02/14] lavc/tiff: Decode embedded JPEGs in DNG images

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Used a technique similar to lavc/tdsc.c for invoking the MJPEG decoder.

This commit adds support for:
- DNG tiles
- DNG tile huffman lossless JPEG decoding
- DNG 8-bpp ("packed" as dcraw calls it) decoding
- DNG color scaling [1]
  - LinearizationTable tag
  - BlackLevel tag

[1]: As specified in the DNG Specification - Chapter 5

Signed-off-by: Nick Renieris 
---
 configure   |   1 +
 libavcodec/Makefile |   2 +-
 libavcodec/tiff.c   | 313 +++-
 libavcodec/tiff.h   |   2 +
 4 files changed, 310 insertions(+), 8 deletions(-)

diff --git a/configure b/configure
index 34c2adb4a4..112b84f0ba 100755
--- a/configure
+++ b/configure
@@ -2817,6 +2817,7 @@ tdsc_decoder_deps="zlib"
 tdsc_decoder_select="mjpeg_decoder"
 theora_decoder_select="vp3_decoder"
 thp_decoder_select="mjpeg_decoder"
+tiff_decoder_select="mjpeg_decoder"
 tiff_decoder_suggest="zlib lzma"
 tiff_encoder_suggest="zlib"
 truehd_decoder_select="mlp_parser"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3cd73fbcc6..f814c69996 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -616,7 +616,7 @@ OBJS-$(CONFIG_TARGA_ENCODER)   += targaenc.o rle.o
 OBJS-$(CONFIG_TARGA_Y216_DECODER)  += targa_y216dec.o
 OBJS-$(CONFIG_TDSC_DECODER)+= tdsc.o
 OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
-OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o 
tiff_common.o
+OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o 
tiff_common.o mjpegdec.o
 OBJS-$(CONFIG_TIFF_ENCODER)+= tiffenc.o rle.o lzwenc.o tiff_data.o
 OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o
 OBJS-$(CONFIG_TRUEHD_DECODER)  += mlpdec.o mlpdsp.o
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index c520d7df83..4c6b835afe 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -35,6 +35,7 @@
 
 #include "libavutil/attributes.h"
 #include "libavutil/avstring.h"
+#include "libavutil/error.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
@@ -46,6 +47,7 @@
 #include "mathops.h"
 #include "tiff.h"
 #include "tiff_data.h"
+#include "mjpegdec.h"
 #include "thread.h"
 #include "get_bits.h"
 
@@ -54,6 +56,10 @@ typedef struct TiffContext {
 AVCodecContext *avctx;
 GetByteContext gb;
 
+/* JPEG decoding for DNG */
+AVCodecContext *avctx_mjpeg; // wrapper context for MJPEG
+AVFrame *jpgframe;   // decoded JPEG tile
+
 int get_subimage;
 uint16_t get_page;
 int get_thumbnail;
@@ -76,7 +82,9 @@ typedef struct TiffContext {
 
 int is_bayer;
 uint8_t pattern[4];
+unsigned black_level;
 unsigned white_level;
+const uint16_t *dng_lut; // Pointer to DNG linearization table
 
 uint32_t sub_ifd;
 uint16_t cur_page;
@@ -86,6 +94,14 @@ typedef struct TiffContext {
 int stripsizesoff, stripsize, stripoff, strippos;
 LZWState *lzw;
 
+/* Tile support */
+int is_tiled;
+int tile_byte_counts_offset, tile_offsets_offset;
+int tile_width, tile_length;
+int tile_count;
+
+int is_jpeg;
+
 uint8_t *deinvert_buf;
 int deinvert_buf_size;
 uint8_t *yuv_line;
@@ -257,6 +273,9 @@ static int add_metadata(int count, int type,
 };
 }
 
+static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
+  const uint8_t *src, int src_stride, int 
width, int height, int is_u16);
+
 static void av_always_inline horizontal_fill(TiffContext *s,
  unsigned int bpp, uint8_t* dst,
  int usePtr, const uint8_t *src,
@@ -712,6 +731,204 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 return 0;
 }
 
+/**
+ * Map stored raw sensor values into linear reference values.
+ * See: DNG Specification - Chapter 5
+ */
+static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
+const uint16_t *lut,
+uint16_t black_level,
+float scale_factor) {
+// Lookup table lookup
+if (lut)
+value = lut[value];
+
+// Black level subtraction
+value = av_clip_uint16_c((unsigned)value - black_level);
+
+// Color scaling
+value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
0x));
+
+return value;
+}
+
+static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+const uint16_t *lut,
+uint1

[FFmpeg-devel] [PATCH v14 06/14] lavc/tiff: Fix edge case with full-length/width tiles

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

In an image [1], the height was equal to the tile length (full-height
tile) and after `height % tile_length` was applied to them with the
current code, it resulted in the operating tile_length to be 0.  This
commit makes this leftover logic only applies if it's necessary.

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 040e83ba7c..14928ed3d5 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -887,10 +887,14 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 int tile_byte_count_offset, tile_byte_count;
 int tile_count_x, tile_count_y;
 int tile_width, tile_length;
+int has_width_leftover, has_height_leftover;
 int tile_x = 0, tile_y = 0;
 int pos_x = 0, pos_y = 0;
 int ret;
 
+has_width_leftover = (s->width % s->tile_width != 0);
+has_height_leftover = (s->height % s->tile_length != 0);
+
 /* Calculate tile counts (round up) */
 tile_count_x = (s->width + s->tile_width - 1) / s->tile_width;
 tile_count_y = (s->height + s->tile_length - 1) / s->tile_length;
@@ -900,12 +904,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 tile_x = tile_idx % tile_count_x;
 tile_y = tile_idx / tile_count_x;
 
-if (tile_x == tile_count_x - 1) // If on the right edge
+if (has_width_leftover && tile_x == tile_count_x - 1) // If on the 
right-most tile
 tile_width = s->width % s->tile_width;
 else
 tile_width = s->tile_width;
 
-if (tile_y == tile_count_y - 1) // If on the bottom edge
+if (has_height_leftover && tile_y == tile_count_y - 1) // If on the 
bottom-most tile
 tile_length = s->height % s->tile_length;
 else
 tile_length = s->tile_length;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 04/14] lavc/tiff: Apply color scaling to uncompressed DNGs

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 25 -
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index a2102f32b5..040e83ba7c 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -556,6 +556,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 int is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB) &&
  (desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
  desc->nb_components >= 3;
+int is_dng;
 
 if (s->planar)
 width /= s->bppcount;
@@ -657,6 +658,8 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 bytestream2_init(&s->gb, src, size);
 bytestream2_init_writer(&pb, dst, is_yuv ? s->yuv_line_size : (stride * 
lines));
 
+is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+
 for (line = 0; line < lines; line++) {
 if (src - ssrc > size) {
 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -679,6 +682,25 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 for (i = 0; i < width; i++)
 dst[i] = ff_reverse[src[i]];
 }
+
+/* Color processing for DNG images with uncompressed strips 
(non-tiled) */
+if (is_dng) {
+int is_u16, pixel_size_bytes, pixel_size_bits;
+
+is_u16 = (s->bpp > 8);
+pixel_size_bits = (is_u16 ? 16 : 8);
+pixel_size_bytes = (is_u16 ? sizeof(uint16_t) : 
sizeof(uint8_t));
+
+dng_blit(s,
+ dst,
+ 0, // no stride, only 1 line
+ dst,
+ 0, // no stride, only 1 line
+ width / pixel_size_bytes * pixel_size_bits / s->bpp, 
// need to account for [1, 16] bpp
+ 1,
+ is_u16);
+}
+
 src += width;
 break;
 case TIFF_PACKBITS:
@@ -1945,7 +1967,8 @@ again:
 FFSWAP(int,  p->linesize[0], p->linesize[1]);
 }
 
-if (s->is_bayer && s->white_level && s->bpp == 16) {
+if (s->is_bayer && s->white_level && s->bpp == 16 &&
+!(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)) {
 uint16_t *dst = (uint16_t *)p->data[0];
 for (i = 0; i < s->height; i++) {
 for (j = 0; j < s->width; j++)
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 07/14] lavc/tiff: Don't apply strips-related logic to tiled images

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 42 ++
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 14928ed3d5..ff9ac30b3f 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1780,7 +1780,7 @@ again:
 }
 }
 
-if (!s->strippos && !s->stripoff) {
+if (!s->is_tiled && !s->strippos && !s->stripoff) {
 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
 return AVERROR_INVALIDDATA;
 }
@@ -1788,27 +1788,29 @@ again:
 if ((ret = init_image(s, &frame)) < 0)
 return ret;
 
-if (s->strips == 1 && !s->stripsize) {
-av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
-s->stripsize = avpkt->size - s->stripoff;
-}
+if (!s->is_tiled) {
+if (s->strips == 1 && !s->stripsize) {
+av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
+s->stripsize = avpkt->size - s->stripoff;
+}
 
-if (s->stripsizesoff) {
-if (s->stripsizesoff >= (unsigned)avpkt->size)
-return AVERROR_INVALIDDATA;
-bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
- avpkt->size - s->stripsizesoff);
-}
-if (s->strippos) {
-if (s->strippos >= (unsigned)avpkt->size)
-return AVERROR_INVALIDDATA;
-bytestream2_init(&stripdata, avpkt->data + s->strippos,
- avpkt->size - s->strippos);
-}
+if (s->stripsizesoff) {
+if (s->stripsizesoff >= (unsigned)avpkt->size)
+return AVERROR_INVALIDDATA;
+bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
+avpkt->size - s->stripsizesoff);
+}
+if (s->strippos) {
+if (s->strippos >= (unsigned)avpkt->size)
+return AVERROR_INVALIDDATA;
+bytestream2_init(&stripdata, avpkt->data + s->strippos,
+avpkt->size - s->strippos);
+}
 
-if (s->rps <= 0 || s->rps % s->subsampling[1]) {
-av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
-return AVERROR_INVALIDDATA;
+if (s->rps <= 0 || s->rps % s->subsampling[1]) {
+av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
+return AVERROR_INVALIDDATA;
+}
 }
 
 /* Handle DNG images with JPEG-compressed tiles */
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 03/14] lavc/tiff: Convert DNGs to sRGB color space

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 34 +++---
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 4c6b835afe..a2102f32b5 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -731,14 +731,23 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 return 0;
 }
 
+static float av_always_inline linear_to_srgb(float value) {
+if (value <= 0.0031308)
+return value * 12.92;
+else
+return pow(value * 1.055, 1.0 / 2.4) - 0.055;
+}
+
 /**
- * Map stored raw sensor values into linear reference values.
- * See: DNG Specification - Chapter 5
+ * Map stored raw sensor values into linear reference values (see: DNG 
Specification - Chapter 5)
+ * Then convert to sRGB color space.
  */
-static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
-const uint16_t *lut,
-uint16_t black_level,
-float scale_factor) {
+static uint16_t av_always_inline dng_process_color16(uint16_t value,
+ const uint16_t *lut,
+ uint16_t black_level,
+ float scale_factor) {
+float value_norm;
+
 // Lookup table lookup
 if (lut)
 value = lut[value];
@@ -747,16 +756,19 @@ static uint16_t av_always_inline 
dng_raw_to_linear16(uint16_t value,
 value = av_clip_uint16_c((unsigned)value - black_level);
 
 // Color scaling
-value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
0x));
+value_norm = (float)value * scale_factor;
+
+// Color space conversion (sRGB)
+value = av_clip_uint16_c((uint16_t)(linear_to_srgb(value_norm) * 0x));
 
 return value;
 }
 
-static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+static uint16_t av_always_inline dng_process_color8(uint16_t value,
 const uint16_t *lut,
 uint16_t black_level,
 float scale_factor) {
-return dng_raw_to_linear16(value, lut, black_level, scale_factor) >> 8;
+return dng_process_color16(value, lut, black_level, scale_factor) >> 8;
 }
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
@@ -774,7 +786,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 uint16_t *src_u16 = (uint16_t *)src;
 
 for (col = 0; col < width; col++)
-*dst_u16++ = dng_raw_to_linear16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
 
 dst += dst_stride * sizeof(uint16_t);
 src += src_stride * sizeof(uint16_t);
@@ -782,7 +794,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 } else {
 for (line = 0; line < height; line++) {
 for (col = 0; col < width; col++)
-*dst++ = dng_raw_to_linear8(*src++, s->dng_lut, 
s->black_level, scale_factor);
+*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
 
 dst += dst_stride;
 src += src_stride;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 09/14] lavc/mjpegdec: Enable decoding of single-component bayer images

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Also, ensure no false positives when determining DNG bayer images, by
setting them in tiff.c instead of relying on a heuristic.  There's no
way to determine this just from the JPEG data, so we have to pass this
information from outside the MJPEG decoder.

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 32 +---
 libavcodec/tiff.c |  7 +++
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 6391107f78..0a920a7144 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -412,13 +412,17 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 return AVERROR_PATCHWELCOME;
 }
 
-/* Lossless JPEGs encoded in DNGs are commonly bayer-encoded. They contain 
2
-   interleaved components and the width stored in their SOF3 markers is the
-   width of each one.  We only output a single component, therefore we need
-   to adjust the output image width. */
-if (s->lossless == 1 && nb_components == 2) {
-s->bayer = 1;
-width *= 2;
+if (s->bayer) {
+if (nb_components == 2) {
+/* Bayer images embedded in DNGs can contain 2 interleaved 
components and the
+   width stored in their SOF3 markers is the width of each one.  
We only output
+   a single component, therefore we need to adjust the output 
image width.  We
+   handle the deinterleaving (but not the debayering) in this 
file. */
+width *= 2;
+}
+/* They can also contain 1 component, which is double the width and 
half the height
+of the final image (rows are interleaved).  We don't handle the 
decoding in this
+file, but leave that to the TIFF/DNG decoder. */
 }
 
 /* if different size, realloc/alloc picture */
@@ -1184,10 +1188,16 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
 ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
 }
-} else if (s->bayer && nb_components == 2) {
-for (mb_x = 0; mb_x < width; mb_x++) {
-((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
-((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+} else if (s->bayer) {
+if (nb_components == 1) {
+/* Leave decoding to the TIFF/DNG decoder (see comment in 
ff_mjpeg_decode_sof) */
+for (mb_x = 0; mb_x < width; mb_x++)
+((uint16_t*)ptr)[mb_x] = buffer[mb_x][0];
+} else if (nb_components == 2) {
+for (mb_x = 0; mb_x < width; mb_x++) {
+((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
+((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+}
 }
 } else {
 for(i=0; igb.buffer;
 jpkt.size = tile_byte_count;
 
+if (s->is_bayer) {
+MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data;
+/* We have to set this information here, there is no way to know if a 
given JPEG is a DNG-embedded
+   image or not from its own data (and we need that information when 
decoding it). */
+mjpegdecctx->bayer = 1;
+}
+
 ret = avcodec_send_packet(s->avctx_mjpeg, &jpkt);
 if (ret < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for 
decoding\n");
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 11/14] lavc/tiff: Decode 14-bit DNG images

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Sample file: 
https://drive.google.com/open?id=0B4JyRT3Lth5HVndyOTVOdWktM3J4TFEydTk1MnY3RWlpSzVB

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 36ede2e2ef..62cfd8d99d 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -309,14 +309,18 @@ static void av_always_inline horizontal_fill(TiffContext 
*s,
 dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4;
 }
 break;
-case 12: {
- uint16_t *dst16 = (uint16_t *)dst;
- GetBitContext gb;
- init_get_bits8(&gb, src, width);
- for (int i = 0; i < s->width; i++) {
- dst16[i] = get_bits(&gb, 12) << 4;
- }
- }
+case 12:
+case 14: {
+uint16_t *dst16 = (uint16_t *)dst;
+int is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+uint8_t shift = is_dng ? 0 : 16 - bpp;
+GetBitContext gb;
+
+init_get_bits8(&gb, src, width);
+for (int i = 0; i < s->width; i++) {
+dst16[i] = get_bits(&gb, bpp) << shift;
+}
+}
 break;
 default:
 if (usePtr) {
@@ -1068,6 +1072,7 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
 }
 break;
 case 10121:
+case 10141:
 switch (AV_RL32(s->pattern)) {
 case 0x02010100:
 s->avctx->pix_fmt = s->le ? AV_PIX_FMT_BAYER_RGGB16LE : 
AV_PIX_FMT_BAYER_RGGB16BE;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 10/14] lavc/tiff: Support decoding of DNGs with single-component JPEGs

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

This enables decoding of DNG images generated by the 'DJI Zenmuse X7'
digital camera
Samples: https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 61 +++
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 39857a64bc..36ede2e2ef 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -274,7 +274,8 @@ static int add_metadata(int count, int type,
 }
 
 static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
-  const uint8_t *src, int src_stride, int 
width, int height, int is_u16);
+  const uint8_t *src, int src_stride, int 
width, int height,
+  int is_single_comp, int is_u16);
 
 static void av_always_inline horizontal_fill(TiffContext *s,
  unsigned int bpp, uint8_t* dst,
@@ -698,6 +699,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
  0, // no stride, only 1 line
  width / pixel_size_bytes * pixel_size_bits / s->bpp, 
// need to account for [1, 16] bpp
  1,
+ 0, // single-component variation is only preset in 
JPEG-encoded DNGs
  is_u16);
 }
 
@@ -795,18 +797,32 @@ static uint16_t av_always_inline 
dng_process_color8(uint16_t value,
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
  const uint8_t *src, int src_stride,
- int width, int height, int is_u16)
+ int width, int height, int is_single_comp, int is_u16)
 {
 int line, col;
 float scale_factor;
 
 scale_factor = 1.0f / (s->white_level - s->black_level);
 
-if (is_u16) {
-for (line = 0; line < height; line++) {
+if (is_single_comp) {
+if (!is_u16)
+return; /* <= 8bpp unsupported */
+
+/* Image is double the width and half the height we need, each row 
comprises 2 rows of the output
+   (split vertically in the middle). */
+for (line = 0; line < height / 2; line++) {
 uint16_t *dst_u16 = (uint16_t *)dst;
 uint16_t *src_u16 = (uint16_t *)src;
 
+/* Blit first half of input row row to initial row of output */
+for (col = 0; col < width; col++)
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+
+/* Advance the destination pointer by a row (source pointer 
remains in the same place) */
+dst += dst_stride * sizeof(uint16_t);
+dst_u16 = (uint16_t *)dst;
+
+/* Blit second half of input row row to next row of output */
 for (col = 0; col < width; col++)
 *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
 
@@ -814,12 +830,27 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 src += src_stride * sizeof(uint16_t);
 }
 } else {
-for (line = 0; line < height; line++) {
-for (col = 0; col < width; col++)
-*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
+/* Input and output image are the same size and the MJpeg decoder has 
done per-component
+   deinterleaving, so blitting here is straightforward. */
+if (is_u16) {
+for (line = 0; line < height; line++) {
+uint16_t *dst_u16 = (uint16_t *)dst;
+uint16_t *src_u16 = (uint16_t *)src;
+
+for (col = 0; col < width; col++)
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+
+dst += dst_stride * sizeof(uint16_t);
+src += src_stride * sizeof(uint16_t);
+}
+} else {
+for (line = 0; line < height; line++) {
+for (col = 0; col < width; col++)
+*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
 
-dst += dst_stride;
-src += src_stride;
+dst += dst_stride;
+src += src_stride;
+}
 }
 }
 }
@@ -831,7 +862,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 AVPacket jpkt;
 uint8_t *dst_data, *src_data;
 uint32_t dst_offset; /* offset from dst buffer in pixels */
-int is_u16, pixel_size;
+int is_single_comp, is_u16, pixel_size;
 int ret;
 
 /* Prepare a packet and send to the MJPEG decoder */
@@ -865,9 +896,18 @@ static int dng_decode_jpeg_tile(AVCod

[FFmpeg-devel] [PATCH v14 08/14] lavc/tiff: Force DNG pixel data endianness on an edge case

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index ff9ac30b3f..709bbfb301 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1038,6 +1038,18 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
AV_RL32(s->pattern));
 return AVERROR_PATCHWELCOME;
 }
+/* Force endianness as mentioned in 'DNG Specification: Chapter 3: 
BitsPerSample'
+NOTE: The spec actually specifies big-endian, not sure why we need 
little-endian,
+  but such images don't work otherwise. */
+if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)
+&& (s->bpp != 8 && s->bpp != 16 && s->bpp != 32)) {
+switch (s->avctx->pix_fmt) {
+case AV_PIX_FMT_BAYER_RGGB16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_RGGB16LE; break;
+case AV_PIX_FMT_BAYER_BGGR16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_BGGR16LE; break;
+case AV_PIX_FMT_BAYER_GBRG16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_GBRG16LE; break;
+case AV_PIX_FMT_BAYER_GRBG16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_GRBG16LE; break;
+}
+}
 break;
 case 10161:
 switch (AV_RL32(s->pattern)) {
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 12/14] lavc/mjpegdec: Skip unknown APPx marker on bayer images

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Samples:
- Embedded JPEG images in the DNG images here:
  https://www.photographyblog.com/previews/pentax_k1_photos

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 0a920a7144..1f2fabe2df 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1807,8 +1807,15 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
 int len, id, i;
 
 len = get_bits(&s->gb, 16);
-if (len < 6)
-return AVERROR_INVALIDDATA;
+if (len < 6) {
+if (s->bayer) {
+// Pentax K-1 (digital camera) JPEG images embedded in DNG images 
contain unknown APP0 markers
+av_log(s->avctx, AV_LOG_WARNING, "skipping APPx (len=%"PRId32") 
for bayer-encoded image\n", len);
+skip_bits(&s->gb, len);
+return 0;
+} else
+return AVERROR_INVALIDDATA;
+}
 if (8 * len > get_bits_left(&s->gb))
 return AVERROR_INVALIDDATA;
 
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 05/14] lavc/jpegtables: Handle multiple mappings to the same value

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Some JPEGs [1] have incorrect DHT entries that map 2 codes to
the same value.

The second (last) mapping does not ever actually appear in the
code stream, therefore ignoring any mappings after the first one
fixes this.

Without this, an "mjpeg_decode_dc: bad vlc: 0:0" error is thrown.

In all known files, the 2 codes are mapped to symbol 0 so only
that case is checked.

---

[1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
 https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/jpegtables.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/libavcodec/jpegtables.c b/libavcodec/jpegtables.c
index cbe5523cb4..fa5c6f9fc5 100644
--- a/libavcodec/jpegtables.c
+++ b/libavcodec/jpegtables.c
@@ -130,14 +130,25 @@ void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, 
uint16_t *huff_code,
 {
 int i, j, k,nb, code, sym;
 
-code = 0;
+/* Some badly encoded files [1] map 2 different codes to symbol 0.
+   Only the first one is valid, so we zero-initialize this here and
+   make sure we only set it once (the first time) in the loop below.
+
+   [1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
+https://www.dji.com/gr/zenmuse-x7/info#downloads
+ */
+huff_size[0] = 0;
+
 k = 0;
+code = 0;
 for(i=1;i<=16;i++) {
 nb = bits_table[i];
 for(j=0;jhttps://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 14/14] lavc/tiff: Default-initialize WhiteLevel DNG tag value

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

Initialized to `(2 ^ BitsPerSample) - 1` as per the DNG Specification.

Also make sure that `BlackLevel < WhiteLevel`.

This fixes decoding for "X7 CinemaDNG" samples here:
- https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index b9aa4efd02..9cf593e092 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1773,6 +1773,7 @@ static int decode_frame(AVCodecContext *avctx,
 GetByteContext stripsizes;
 GetByteContext stripdata;
 int retry_for_subifd, retry_for_page;
+int is_dng;
 
 bytestream2_init(&s->gb, avpkt->data, avpkt->size);
 
@@ -1841,6 +1842,10 @@ again:
 goto again;
 }
 
+/* At this point we've decided on which (Sub)IFD to process */
+
+is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+
 for (i = 0; igeotag_count; i++) {
 const char *keyname = get_geokey_name(s->geotags[i].key);
 if (!keyname) {
@@ -1858,10 +1863,22 @@ again:
 }
 }
 
+if (is_dng) {
+if (s->white_level == 0)
+s->white_level = (1 << s->bpp) - 1; /* Default value as per the 
spec */
+
+if (s->white_level <= s->black_level) {
+av_log(avctx, AV_LOG_ERROR, "BlackLevel (%"PRId32") must be less 
than WhiteLevel (%"PRId32")\n",
+s->black_level, s->white_level);
+return AVERROR_INVALIDDATA;
+}
+}
+
 if (!s->is_tiled && !s->strippos && !s->stripoff) {
 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
 return AVERROR_INVALIDDATA;
 }
+
 /* now we have the data and may start decoding */
 if ((ret = init_image(s, &frame)) < 0)
 return ret;
@@ -1893,7 +1910,7 @@ again:
 
 /* Handle DNG images with JPEG-compressed tiles */
 
-if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG) 
&& s->is_tiled) {
+if (is_dng && s->is_tiled) {
 if (!s->is_jpeg) {
 avpriv_report_missing_feature(avctx, "DNG uncompressed tiled 
images");
 return AVERROR_PATCHWELCOME;
@@ -2051,8 +2068,7 @@ again:
 FFSWAP(int,  p->linesize[0], p->linesize[1]);
 }
 
-if (s->is_bayer && s->white_level && s->bpp == 16 &&
-!(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)) {
+if (s->is_bayer && s->white_level && s->bpp == 16 && !is_dng) {
 uint16_t *dst = (uint16_t *)p->data[0];
 for (i = 0; i < s->height; i++) {
 for (j = 0; j < s->width; j++)
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v14 13/14] lavc/tiff: Support DNGs with striped (non-tiled) JPEGs images

2019-08-11 Thread Nick Renieris
From: Nick Renieris 

DNG samples here can now be decoded:
- https://www.photographyblog.com/previews/pentax_k1_photos

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 61 ---
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 62cfd8d99d..b9aa4efd02 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -550,6 +550,8 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, 
int stride,
 return ret;
 }
 
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame);
+
 static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int 
stride,
  const uint8_t *src, int size, int strip_start, 
int lines)
 {
@@ -665,6 +667,17 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 
 is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
 
+/* Decode JPEG-encoded DNGs with strips */
+if (s->compr == TIFF_NEWJPEG && is_dng) {
+if (s->strips > 1) {
+av_log(s->avctx, AV_LOG_ERROR, "More than one DNG JPEG strips 
unsupported\n");
+return AVERROR_PATCHWELCOME;
+}
+if ((ret = dng_decode_strip(s->avctx, p)) < 0)
+return ret;
+return 0;
+}
+
 for (line = 0; line < lines; line++) {
 if (src - ssrc > size) {
 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -859,8 +872,8 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 }
 }
 
-static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame,
-int tile_byte_count, int x, int y, int w, int 
h)
+static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame,
+   int tile_byte_count, int dst_x, int dst_y, int w, 
int h)
 {
 TiffContext *s = avctx->priv_data;
 AVPacket jpkt;
@@ -912,7 +925,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 return AVERROR_PATCHWELCOME;
 }
 
-dst_offset = x + frame->linesize[0] * y / pixel_size;
+dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size;
 dst_data = frame->data[0] + dst_offset * pixel_size;
 src_data = s->jpgframe->data[0];
 
@@ -931,7 +944,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 return 0;
 }
 
-static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame)
+static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, AVPacket 
*avpkt)
 {
 TiffContext *s = avctx->priv_data;
 int tile_idx;
@@ -944,6 +957,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame 
*frame)
 int pos_x = 0, pos_y = 0;
 int ret;
 
+s->jpgframe->width  = s->tile_width;
+s->jpgframe->height = s->tile_length;
+
+s->avctx_mjpeg->width = s->tile_width;
+s->avctx_mjpeg->height = s->tile_length;
+
 has_width_leftover = (s->width % s->tile_width != 0);
 has_height_leftover = (s->height % s->tile_length != 0);
 
@@ -980,7 +999,7 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame 
*frame)
 bytestream2_seek(&s->gb, tile_offset, SEEK_SET);
 
 /* Decode JPEG tile and copy it in the reference frame */
-ret = dng_decode_jpeg_tile(avctx, frame, tile_byte_count, pos_x, 
pos_y, tile_width, tile_length);
+ret = dng_decode_jpeg(avctx, frame, tile_byte_count, pos_x, pos_y, 
tile_width, tile_length);
 
 if (ret < 0)
 return ret;
@@ -993,30 +1012,24 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 }
 }
 
-return 0;
-}
+/* Frame is ready to be output */
+frame->pict_type = AV_PICTURE_TYPE_I;
+frame->key_frame = 1;
 
-static int dng_decode(AVCodecContext *avctx, AVFrame *frame, AVPacket *avpkt) {
-int ret;
+return avpkt->size;
+}
 
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame)
+{
 TiffContext *s = avctx->priv_data;
 
-s->jpgframe->width  = s->tile_width;
-s->jpgframe->height = s->tile_length;
-
-s->avctx_mjpeg->width = s->tile_width;
-s->avctx_mjpeg->height = s->tile_length;
-
-/* Decode all tiles in a frame */
-ret = dng_decode_tiles(avctx, frame);
-if (ret < 0)
-return ret;
+s->jpgframe->width  = s->width;
+s->jpgframe->height = s->height;
 
-/* Frame is ready to be output */
-frame->pict_type = AV_PICTURE_TYPE_I;
-frame->key_frame = 1;
+s->avctx_mjpeg->width = s->width;
+s->avctx_mjpeg->height = s->height;
 
-return avpkt->size;
+return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, 
s->height);
 }
 
 stat

[FFmpeg-devel] [PATCH v15 06/15] lavc/tiff: Fix edge case with full-length/width tiles

2019-08-20 Thread Nick Renieris
In an image [1], the height was equal to the tile length (full-height
tile) and after `height % tile_length` was applied to them with the
current code, it resulted in the operating tile_length to be 0.  This
commit makes this leftover logic only applies if it's necessary.

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index dd1295fad6..257230c386 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -887,10 +887,14 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 int tile_byte_count_offset, tile_byte_count;
 int tile_count_x, tile_count_y;
 int tile_width, tile_length;
+int has_width_leftover, has_height_leftover;
 int tile_x = 0, tile_y = 0;
 int pos_x = 0, pos_y = 0;
 int ret;
 
+has_width_leftover = (s->width % s->tile_width != 0);
+has_height_leftover = (s->height % s->tile_length != 0);
+
 /* Calculate tile counts (round up) */
 tile_count_x = (s->width + s->tile_width - 1) / s->tile_width;
 tile_count_y = (s->height + s->tile_length - 1) / s->tile_length;
@@ -900,12 +904,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 tile_x = tile_idx % tile_count_x;
 tile_y = tile_idx / tile_count_x;
 
-if (tile_x == tile_count_x - 1) // If on the right edge
+if (has_width_leftover && tile_x == tile_count_x - 1) // If on the 
right-most tile
 tile_width = s->width % s->tile_width;
 else
 tile_width = s->tile_width;
 
-if (tile_y == tile_count_y - 1) // If on the bottom edge
+if (has_height_leftover && tile_y == tile_count_y - 1) // If on the 
bottom-most tile
 tile_length = s->height % s->tile_length;
 else
 tile_length = s->tile_length;
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v15 10/15] lavc/tiff: Support decoding of DNGs with single-component JPEGs

2019-08-20 Thread Nick Renieris
This enables decoding of DNG images generated by the 'DJI Zenmuse X7'
digital camera
Samples: https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 61 +++
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 77acf9f838..35234dc05e 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -274,7 +274,8 @@ static int add_metadata(int count, int type,
 }
 
 static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
-  const uint8_t *src, int src_stride, int 
width, int height, int is_u16);
+  const uint8_t *src, int src_stride, int 
width, int height,
+  int is_single_comp, int is_u16);
 
 static void av_always_inline horizontal_fill(TiffContext *s,
  unsigned int bpp, uint8_t* dst,
@@ -698,6 +699,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
  0, // no stride, only 1 line
  width / pixel_size_bytes * pixel_size_bits / s->bpp * 
s->bppcount, // need to account for [1, 16] bpp
  1,
+ 0, // single-component variation is only preset in 
JPEG-encoded DNGs
  is_u16);
 }
 
@@ -795,18 +797,32 @@ static uint16_t av_always_inline 
dng_process_color8(uint16_t value,
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
  const uint8_t *src, int src_stride,
- int width, int height, int is_u16)
+ int width, int height, int is_single_comp, int is_u16)
 {
 int line, col;
 float scale_factor;
 
 scale_factor = 1.0f / (s->white_level - s->black_level);
 
-if (is_u16) {
-for (line = 0; line < height; line++) {
+if (is_single_comp) {
+if (!is_u16)
+return; /* <= 8bpp unsupported */
+
+/* Image is double the width and half the height we need, each row 
comprises 2 rows of the output
+   (split vertically in the middle). */
+for (line = 0; line < height / 2; line++) {
 uint16_t *dst_u16 = (uint16_t *)dst;
 uint16_t *src_u16 = (uint16_t *)src;
 
+/* Blit first half of input row row to initial row of output */
+for (col = 0; col < width; col++)
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+
+/* Advance the destination pointer by a row (source pointer 
remains in the same place) */
+dst += dst_stride * sizeof(uint16_t);
+dst_u16 = (uint16_t *)dst;
+
+/* Blit second half of input row row to next row of output */
 for (col = 0; col < width; col++)
 *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
 
@@ -814,12 +830,27 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 src += src_stride * sizeof(uint16_t);
 }
 } else {
-for (line = 0; line < height; line++) {
-for (col = 0; col < width; col++)
-*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
+/* Input and output image are the same size and the MJpeg decoder has 
done per-component
+   deinterleaving, so blitting here is straightforward. */
+if (is_u16) {
+for (line = 0; line < height; line++) {
+uint16_t *dst_u16 = (uint16_t *)dst;
+uint16_t *src_u16 = (uint16_t *)src;
+
+for (col = 0; col < width; col++)
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+
+dst += dst_stride * sizeof(uint16_t);
+src += src_stride * sizeof(uint16_t);
+}
+} else {
+for (line = 0; line < height; line++) {
+for (col = 0; col < width; col++)
+*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
 
-dst += dst_stride;
-src += src_stride;
+dst += dst_stride;
+src += src_stride;
+}
 }
 }
 }
@@ -831,7 +862,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 AVPacket jpkt;
 uint8_t *dst_data, *src_data;
 uint32_t dst_offset; /* offset from dst buffer in pixels */
-int is_u16, pixel_size;
+int is_single_comp, is_u16, pixel_size;
 int ret;
 
 /* Prepare a packet and send to the MJPEG decoder */
@@ -865,9 +896,18 @@ static int dng_decode_jpeg_tile(AVCodecContext *

[FFmpeg-devel] [PATCH v15 11/15] lavc/tiff: Decode 10-bit and 14-bit DNG images

2019-08-20 Thread Nick Renieris
10-bit sample: http://www.rawsamples.ch/raws/phones/RAW_ONEPLUS_ONE-A0001.DNG
14-bit sample: 
https://drive.google.com/open?id=0B4JyRT3Lth5HVndyOTVOdWktM3J4TFEydTk1MnY3RWlpSzVB

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 35234dc05e..d5efd05d7c 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -309,14 +309,19 @@ static void av_always_inline horizontal_fill(TiffContext 
*s,
 dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4;
 }
 break;
-case 12: {
- uint16_t *dst16 = (uint16_t *)dst;
- GetBitContext gb;
- init_get_bits8(&gb, src, width);
- for (int i = 0; i < s->width; i++) {
- dst16[i] = get_bits(&gb, 12) << 4;
- }
- }
+case 10:
+case 12:
+case 14: {
+uint16_t *dst16 = (uint16_t *)dst;
+int is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+uint8_t shift = is_dng ? 0 : 16 - bpp;
+GetBitContext gb;
+
+init_get_bits8(&gb, src, width);
+for (int i = 0; i < s->width; i++) {
+dst16[i] = get_bits(&gb, bpp) << shift;
+}
+}
 break;
 default:
 if (usePtr) {
@@ -1067,7 +1072,9 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
 return AVERROR_PATCHWELCOME;
 }
 break;
+case 10101:
 case 10121:
+case 10141:
 switch (AV_RL32(s->pattern)) {
 case 0x02010100:
 s->avctx->pix_fmt = s->le ? AV_PIX_FMT_BAYER_RGGB16LE : 
AV_PIX_FMT_BAYER_RGGB16BE;
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v15 12/15] lavc/mjpegdec: Skip unknown APPx marker on bayer images

2019-08-20 Thread Nick Renieris
Samples:
- Embedded JPEG images in the DNG images here:
  https://www.photographyblog.com/previews/pentax_k1_photos

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 0a920a7144..1f2fabe2df 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1807,8 +1807,15 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
 int len, id, i;
 
 len = get_bits(&s->gb, 16);
-if (len < 6)
-return AVERROR_INVALIDDATA;
+if (len < 6) {
+if (s->bayer) {
+// Pentax K-1 (digital camera) JPEG images embedded in DNG images 
contain unknown APP0 markers
+av_log(s->avctx, AV_LOG_WARNING, "skipping APPx (len=%"PRId32") 
for bayer-encoded image\n", len);
+skip_bits(&s->gb, len);
+return 0;
+} else
+return AVERROR_INVALIDDATA;
+}
 if (8 * len > get_bits_left(&s->gb))
 return AVERROR_INVALIDDATA;
 
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v15 14/15] lavc/tiff: Default-initialize WhiteLevel DNG tag value

2019-08-20 Thread Nick Renieris
Initialized to `(2 ^ BitsPerSample) - 1` as per the DNG Specification.

Also make sure that `BlackLevel < WhiteLevel`.

This fixes decoding for "X7 CinemaDNG" samples here:
- https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index df2554be86..377662c897 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1775,6 +1775,7 @@ static int decode_frame(AVCodecContext *avctx,
 GetByteContext stripsizes;
 GetByteContext stripdata;
 int retry_for_subifd, retry_for_page;
+int is_dng;
 
 bytestream2_init(&s->gb, avpkt->data, avpkt->size);
 
@@ -1843,6 +1844,10 @@ again:
 goto again;
 }
 
+/* At this point we've decided on which (Sub)IFD to process */
+
+is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+
 for (i = 0; igeotag_count; i++) {
 const char *keyname = get_geokey_name(s->geotags[i].key);
 if (!keyname) {
@@ -1860,10 +1865,22 @@ again:
 }
 }
 
+if (is_dng) {
+if (s->white_level == 0)
+s->white_level = (1 << s->bpp) - 1; /* Default value as per the 
spec */
+
+if (s->white_level <= s->black_level) {
+av_log(avctx, AV_LOG_ERROR, "BlackLevel (%"PRId32") must be less 
than WhiteLevel (%"PRId32")\n",
+s->black_level, s->white_level);
+return AVERROR_INVALIDDATA;
+}
+}
+
 if (!s->is_tiled && !s->strippos && !s->stripoff) {
 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
 return AVERROR_INVALIDDATA;
 }
+
 /* now we have the data and may start decoding */
 if ((ret = init_image(s, &frame)) < 0)
 return ret;
@@ -1895,7 +1912,7 @@ again:
 
 /* Handle DNG images with JPEG-compressed tiles */
 
-if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG) 
&& s->is_tiled) {
+if (is_dng && s->is_tiled) {
 if (!s->is_jpeg) {
 avpriv_report_missing_feature(avctx, "DNG uncompressed tiled 
images");
 return AVERROR_PATCHWELCOME;
@@ -2053,8 +2070,7 @@ again:
 FFSWAP(int,  p->linesize[0], p->linesize[1]);
 }
 
-if (s->is_bayer && s->white_level && s->bpp == 16 &&
-!(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)) {
+if (s->is_bayer && s->white_level && s->bpp == 16 && !is_dng) {
 uint16_t *dst = (uint16_t *)p->data[0];
 for (i = 0; i < s->height; i++) {
 for (j = 0; j < s->width; j++)
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v15 08/15] lavc/tiff: Force DNG pixel data endianness on an edge case

2019-08-20 Thread Nick Renieris
Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 1ca9a59dbf..d9750891d4 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1038,6 +1038,18 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
AV_RL32(s->pattern));
 return AVERROR_PATCHWELCOME;
 }
+/* Force endianness as mentioned in 'DNG Specification: Chapter 3: 
BitsPerSample'
+NOTE: The spec actually specifies big-endian, not sure why we need 
little-endian,
+  but such images don't work otherwise. */
+if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)
+&& (s->bpp != 8 && s->bpp != 16 && s->bpp != 32)) {
+switch (s->avctx->pix_fmt) {
+case AV_PIX_FMT_BAYER_RGGB16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_RGGB16LE; break;
+case AV_PIX_FMT_BAYER_BGGR16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_BGGR16LE; break;
+case AV_PIX_FMT_BAYER_GBRG16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_GBRG16LE; break;
+case AV_PIX_FMT_BAYER_GRBG16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_GRBG16LE; break;
+}
+}
 break;
 case 10161:
 switch (AV_RL32(s->pattern)) {
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v15 15/15] lavc/tiff: Enable decoding of LinearRaw images

2019-08-20 Thread Nick Renieris
"LinearRaw" is a value that the PhotometricInterpretation tag can be set
to on DNG images that contain color information for all channels instead
of being bayer-encoded ("CFA" value).

The DNG decoder is complete enough that we can enable this now.

Sample:
- http://www.rawsamples.ch/raws/nikon/SCANNER_NIKON_LS5000.DNG

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 377662c897..3166a3e5c8 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1495,6 +1495,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
 case TIFF_PHOTOMETRIC_SEPARATED:
 case TIFF_PHOTOMETRIC_YCBCR:
 case TIFF_PHOTOMETRIC_CFA:
+case TIFF_PHOTOMETRIC_LINEAR_RAW: // Used by DNG images
 s->photometric = value;
 break;
 case TIFF_PHOTOMETRIC_ALPHA_MASK:
@@ -1503,7 +1504,6 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
 case TIFF_PHOTOMETRIC_ITU_LAB:
 case TIFF_PHOTOMETRIC_LOG_L:
 case TIFF_PHOTOMETRIC_LOG_LUV:
-case TIFF_PHOTOMETRIC_LINEAR_RAW:
 avpriv_report_missing_feature(s->avctx,
   "PhotometricInterpretation 0x%04X",
   value);
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v15 04/15] lavc/tiff: Apply color scaling to uncompressed DNGs

2019-08-20 Thread Nick Renieris
Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 25 -
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index a2102f32b5..dd1295fad6 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -556,6 +556,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 int is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB) &&
  (desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
  desc->nb_components >= 3;
+int is_dng;
 
 if (s->planar)
 width /= s->bppcount;
@@ -657,6 +658,8 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 bytestream2_init(&s->gb, src, size);
 bytestream2_init_writer(&pb, dst, is_yuv ? s->yuv_line_size : (stride * 
lines));
 
+is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+
 for (line = 0; line < lines; line++) {
 if (src - ssrc > size) {
 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -679,6 +682,25 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 for (i = 0; i < width; i++)
 dst[i] = ff_reverse[src[i]];
 }
+
+/* Color processing for DNG images with uncompressed strips 
(non-tiled) */
+if (is_dng) {
+int is_u16, pixel_size_bytes, pixel_size_bits;
+
+is_u16 = (s->bpp > 8);
+pixel_size_bits = (is_u16 ? 16 : 8);
+pixel_size_bytes = (is_u16 ? sizeof(uint16_t) : 
sizeof(uint8_t));
+
+dng_blit(s,
+ dst,
+ 0, // no stride, only 1 line
+ dst,
+ 0, // no stride, only 1 line
+ width / pixel_size_bytes * pixel_size_bits / s->bpp * 
s->bppcount, // need to account for [1, 16] bpp
+ 1,
+ is_u16);
+}
+
 src += width;
 break;
 case TIFF_PACKBITS:
@@ -1945,7 +1967,8 @@ again:
 FFSWAP(int,  p->linesize[0], p->linesize[1]);
 }
 
-if (s->is_bayer && s->white_level && s->bpp == 16) {
+if (s->is_bayer && s->white_level && s->bpp == 16 &&
+!(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)) {
 uint16_t *dst = (uint16_t *)p->data[0];
 for (i = 0; i < s->height; i++) {
 for (j = 0; j < s->width; j++)
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v15 09/15] lavc/mjpegdec: Enable decoding of single-component bayer images

2019-08-20 Thread Nick Renieris
Also, ensure no false positives when determining DNG bayer images, by
setting them in tiff.c instead of relying on a heuristic.  There's no
way to determine this just from the JPEG data, so we have to pass this
information from outside the MJPEG decoder.

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 32 +---
 libavcodec/tiff.c |  7 +++
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 6391107f78..0a920a7144 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -412,13 +412,17 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 return AVERROR_PATCHWELCOME;
 }
 
-/* Lossless JPEGs encoded in DNGs are commonly bayer-encoded. They contain 
2
-   interleaved components and the width stored in their SOF3 markers is the
-   width of each one.  We only output a single component, therefore we need
-   to adjust the output image width. */
-if (s->lossless == 1 && nb_components == 2) {
-s->bayer = 1;
-width *= 2;
+if (s->bayer) {
+if (nb_components == 2) {
+/* Bayer images embedded in DNGs can contain 2 interleaved 
components and the
+   width stored in their SOF3 markers is the width of each one.  
We only output
+   a single component, therefore we need to adjust the output 
image width.  We
+   handle the deinterleaving (but not the debayering) in this 
file. */
+width *= 2;
+}
+/* They can also contain 1 component, which is double the width and 
half the height
+of the final image (rows are interleaved).  We don't handle the 
decoding in this
+file, but leave that to the TIFF/DNG decoder. */
 }
 
 /* if different size, realloc/alloc picture */
@@ -1184,10 +1188,16 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
 ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
 }
-} else if (s->bayer && nb_components == 2) {
-for (mb_x = 0; mb_x < width; mb_x++) {
-((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
-((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+} else if (s->bayer) {
+if (nb_components == 1) {
+/* Leave decoding to the TIFF/DNG decoder (see comment in 
ff_mjpeg_decode_sof) */
+for (mb_x = 0; mb_x < width; mb_x++)
+((uint16_t*)ptr)[mb_x] = buffer[mb_x][0];
+} else if (nb_components == 2) {
+for (mb_x = 0; mb_x < width; mb_x++) {
+((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
+((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+}
 }
 } else {
 for(i=0; igb.buffer;
 jpkt.size = tile_byte_count;
 
+if (s->is_bayer) {
+MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data;
+/* We have to set this information here, there is no way to know if a 
given JPEG is a DNG-embedded
+   image or not from its own data (and we need that information when 
decoding it). */
+mjpegdecctx->bayer = 1;
+}
+
 ret = avcodec_send_packet(s->avctx_mjpeg, &jpkt);
 if (ret < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for 
decoding\n");
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v15 02/15] lavc/tiff: Decode embedded JPEGs in DNG images

2019-08-20 Thread Nick Renieris
Used a technique similar to lavc/tdsc.c for invoking the MJPEG decoder.

This commit adds support for:
- DNG tiles
- DNG tile huffman lossless JPEG decoding
- DNG 8-bpp ("packed" as dcraw calls it) decoding
- DNG color scaling [1]
  - LinearizationTable tag
  - BlackLevel tag

[1]: As specified in the DNG Specification - Chapter 5

Signed-off-by: Nick Renieris 
---
 configure   |   1 +
 libavcodec/Makefile |   2 +-
 libavcodec/tiff.c   | 313 +++-
 libavcodec/tiff.h   |   2 +
 4 files changed, 310 insertions(+), 8 deletions(-)

diff --git a/configure b/configure
index 34c2adb4a4..112b84f0ba 100755
--- a/configure
+++ b/configure
@@ -2817,6 +2817,7 @@ tdsc_decoder_deps="zlib"
 tdsc_decoder_select="mjpeg_decoder"
 theora_decoder_select="vp3_decoder"
 thp_decoder_select="mjpeg_decoder"
+tiff_decoder_select="mjpeg_decoder"
 tiff_decoder_suggest="zlib lzma"
 tiff_encoder_suggest="zlib"
 truehd_decoder_select="mlp_parser"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3cd73fbcc6..f814c69996 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -616,7 +616,7 @@ OBJS-$(CONFIG_TARGA_ENCODER)   += targaenc.o rle.o
 OBJS-$(CONFIG_TARGA_Y216_DECODER)  += targa_y216dec.o
 OBJS-$(CONFIG_TDSC_DECODER)+= tdsc.o
 OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
-OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o 
tiff_common.o
+OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o 
tiff_common.o mjpegdec.o
 OBJS-$(CONFIG_TIFF_ENCODER)+= tiffenc.o rle.o lzwenc.o tiff_data.o
 OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o
 OBJS-$(CONFIG_TRUEHD_DECODER)  += mlpdec.o mlpdsp.o
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index c520d7df83..4c6b835afe 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -35,6 +35,7 @@
 
 #include "libavutil/attributes.h"
 #include "libavutil/avstring.h"
+#include "libavutil/error.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
@@ -46,6 +47,7 @@
 #include "mathops.h"
 #include "tiff.h"
 #include "tiff_data.h"
+#include "mjpegdec.h"
 #include "thread.h"
 #include "get_bits.h"
 
@@ -54,6 +56,10 @@ typedef struct TiffContext {
 AVCodecContext *avctx;
 GetByteContext gb;
 
+/* JPEG decoding for DNG */
+AVCodecContext *avctx_mjpeg; // wrapper context for MJPEG
+AVFrame *jpgframe;   // decoded JPEG tile
+
 int get_subimage;
 uint16_t get_page;
 int get_thumbnail;
@@ -76,7 +82,9 @@ typedef struct TiffContext {
 
 int is_bayer;
 uint8_t pattern[4];
+unsigned black_level;
 unsigned white_level;
+const uint16_t *dng_lut; // Pointer to DNG linearization table
 
 uint32_t sub_ifd;
 uint16_t cur_page;
@@ -86,6 +94,14 @@ typedef struct TiffContext {
 int stripsizesoff, stripsize, stripoff, strippos;
 LZWState *lzw;
 
+/* Tile support */
+int is_tiled;
+int tile_byte_counts_offset, tile_offsets_offset;
+int tile_width, tile_length;
+int tile_count;
+
+int is_jpeg;
+
 uint8_t *deinvert_buf;
 int deinvert_buf_size;
 uint8_t *yuv_line;
@@ -257,6 +273,9 @@ static int add_metadata(int count, int type,
 };
 }
 
+static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
+  const uint8_t *src, int src_stride, int 
width, int height, int is_u16);
+
 static void av_always_inline horizontal_fill(TiffContext *s,
  unsigned int bpp, uint8_t* dst,
  int usePtr, const uint8_t *src,
@@ -712,6 +731,204 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 return 0;
 }
 
+/**
+ * Map stored raw sensor values into linear reference values.
+ * See: DNG Specification - Chapter 5
+ */
+static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
+const uint16_t *lut,
+uint16_t black_level,
+float scale_factor) {
+// Lookup table lookup
+if (lut)
+value = lut[value];
+
+// Black level subtraction
+value = av_clip_uint16_c((unsigned)value - black_level);
+
+// Color scaling
+value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
0x));
+
+return value;
+}
+
+static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+const uint16_t *lut,
+uint16_t black_level,
+ 

[FFmpeg-devel] [PATCH v15 07/15] lavc/tiff: Don't apply strips-related logic to tiled images

2019-08-20 Thread Nick Renieris
Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 42 ++
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 257230c386..1ca9a59dbf 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1780,7 +1780,7 @@ again:
 }
 }
 
-if (!s->strippos && !s->stripoff) {
+if (!s->is_tiled && !s->strippos && !s->stripoff) {
 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
 return AVERROR_INVALIDDATA;
 }
@@ -1788,27 +1788,29 @@ again:
 if ((ret = init_image(s, &frame)) < 0)
 return ret;
 
-if (s->strips == 1 && !s->stripsize) {
-av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
-s->stripsize = avpkt->size - s->stripoff;
-}
+if (!s->is_tiled) {
+if (s->strips == 1 && !s->stripsize) {
+av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
+s->stripsize = avpkt->size - s->stripoff;
+}
 
-if (s->stripsizesoff) {
-if (s->stripsizesoff >= (unsigned)avpkt->size)
-return AVERROR_INVALIDDATA;
-bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
- avpkt->size - s->stripsizesoff);
-}
-if (s->strippos) {
-if (s->strippos >= (unsigned)avpkt->size)
-return AVERROR_INVALIDDATA;
-bytestream2_init(&stripdata, avpkt->data + s->strippos,
- avpkt->size - s->strippos);
-}
+if (s->stripsizesoff) {
+if (s->stripsizesoff >= (unsigned)avpkt->size)
+return AVERROR_INVALIDDATA;
+bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
+avpkt->size - s->stripsizesoff);
+}
+if (s->strippos) {
+if (s->strippos >= (unsigned)avpkt->size)
+return AVERROR_INVALIDDATA;
+bytestream2_init(&stripdata, avpkt->data + s->strippos,
+avpkt->size - s->strippos);
+}
 
-if (s->rps <= 0 || s->rps % s->subsampling[1]) {
-av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
-return AVERROR_INVALIDDATA;
+if (s->rps <= 0 || s->rps % s->subsampling[1]) {
+av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
+return AVERROR_INVALIDDATA;
+}
 }
 
 /* Handle DNG images with JPEG-compressed tiles */
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v15 13/15] lavc/tiff: Support DNGs with striped (non-tiled) JPEGs images

2019-08-20 Thread Nick Renieris
DNG samples here can now be decoded:
- https://www.photographyblog.com/previews/pentax_k1_photos

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 61 ---
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index d5efd05d7c..df2554be86 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -551,6 +551,8 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, 
int stride,
 return ret;
 }
 
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame);
+
 static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int 
stride,
  const uint8_t *src, int size, int strip_start, 
int lines)
 {
@@ -666,6 +668,17 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 
 is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
 
+/* Decode JPEG-encoded DNGs with strips */
+if (s->compr == TIFF_NEWJPEG && is_dng) {
+if (s->strips > 1) {
+av_log(s->avctx, AV_LOG_ERROR, "More than one DNG JPEG strips 
unsupported\n");
+return AVERROR_PATCHWELCOME;
+}
+if ((ret = dng_decode_strip(s->avctx, p)) < 0)
+return ret;
+return 0;
+}
+
 for (line = 0; line < lines; line++) {
 if (src - ssrc > size) {
 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -860,8 +873,8 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 }
 }
 
-static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame,
-int tile_byte_count, int x, int y, int w, int 
h)
+static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame,
+   int tile_byte_count, int dst_x, int dst_y, int w, 
int h)
 {
 TiffContext *s = avctx->priv_data;
 AVPacket jpkt;
@@ -913,7 +926,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 return AVERROR_PATCHWELCOME;
 }
 
-dst_offset = x + frame->linesize[0] * y / pixel_size;
+dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size;
 dst_data = frame->data[0] + dst_offset * pixel_size;
 src_data = s->jpgframe->data[0];
 
@@ -932,7 +945,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 return 0;
 }
 
-static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame)
+static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, AVPacket 
*avpkt)
 {
 TiffContext *s = avctx->priv_data;
 int tile_idx;
@@ -945,6 +958,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame 
*frame)
 int pos_x = 0, pos_y = 0;
 int ret;
 
+s->jpgframe->width  = s->tile_width;
+s->jpgframe->height = s->tile_length;
+
+s->avctx_mjpeg->width = s->tile_width;
+s->avctx_mjpeg->height = s->tile_length;
+
 has_width_leftover = (s->width % s->tile_width != 0);
 has_height_leftover = (s->height % s->tile_length != 0);
 
@@ -981,7 +1000,7 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame 
*frame)
 bytestream2_seek(&s->gb, tile_offset, SEEK_SET);
 
 /* Decode JPEG tile and copy it in the reference frame */
-ret = dng_decode_jpeg_tile(avctx, frame, tile_byte_count, pos_x, 
pos_y, tile_width, tile_length);
+ret = dng_decode_jpeg(avctx, frame, tile_byte_count, pos_x, pos_y, 
tile_width, tile_length);
 
 if (ret < 0)
 return ret;
@@ -994,30 +1013,24 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 }
 }
 
-return 0;
-}
+/* Frame is ready to be output */
+frame->pict_type = AV_PICTURE_TYPE_I;
+frame->key_frame = 1;
 
-static int dng_decode(AVCodecContext *avctx, AVFrame *frame, AVPacket *avpkt) {
-int ret;
+return avpkt->size;
+}
 
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame)
+{
 TiffContext *s = avctx->priv_data;
 
-s->jpgframe->width  = s->tile_width;
-s->jpgframe->height = s->tile_length;
-
-s->avctx_mjpeg->width = s->tile_width;
-s->avctx_mjpeg->height = s->tile_length;
-
-/* Decode all tiles in a frame */
-ret = dng_decode_tiles(avctx, frame);
-if (ret < 0)
-return ret;
+s->jpgframe->width  = s->width;
+s->jpgframe->height = s->height;
 
-/* Frame is ready to be output */
-frame->pict_type = AV_PICTURE_TYPE_I;
-frame->key_frame = 1;
+s->avctx_mjpeg->width = s->width;
+s->avctx_mjpeg->height = s->height;
 
-return avpkt->size;
+return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, 
s->height);
 }
 
 static int init_image(TiffContext *s, Thr

[FFmpeg-devel] [PATCH v15 03/15] lavc/tiff: Convert DNGs to sRGB color space

2019-08-20 Thread Nick Renieris
Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 34 +++---
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 4c6b835afe..a2102f32b5 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -731,14 +731,23 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 return 0;
 }
 
+static float av_always_inline linear_to_srgb(float value) {
+if (value <= 0.0031308)
+return value * 12.92;
+else
+return pow(value * 1.055, 1.0 / 2.4) - 0.055;
+}
+
 /**
- * Map stored raw sensor values into linear reference values.
- * See: DNG Specification - Chapter 5
+ * Map stored raw sensor values into linear reference values (see: DNG 
Specification - Chapter 5)
+ * Then convert to sRGB color space.
  */
-static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
-const uint16_t *lut,
-uint16_t black_level,
-float scale_factor) {
+static uint16_t av_always_inline dng_process_color16(uint16_t value,
+ const uint16_t *lut,
+ uint16_t black_level,
+ float scale_factor) {
+float value_norm;
+
 // Lookup table lookup
 if (lut)
 value = lut[value];
@@ -747,16 +756,19 @@ static uint16_t av_always_inline 
dng_raw_to_linear16(uint16_t value,
 value = av_clip_uint16_c((unsigned)value - black_level);
 
 // Color scaling
-value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
0x));
+value_norm = (float)value * scale_factor;
+
+// Color space conversion (sRGB)
+value = av_clip_uint16_c((uint16_t)(linear_to_srgb(value_norm) * 0x));
 
 return value;
 }
 
-static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+static uint16_t av_always_inline dng_process_color8(uint16_t value,
 const uint16_t *lut,
 uint16_t black_level,
 float scale_factor) {
-return dng_raw_to_linear16(value, lut, black_level, scale_factor) >> 8;
+return dng_process_color16(value, lut, black_level, scale_factor) >> 8;
 }
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
@@ -774,7 +786,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 uint16_t *src_u16 = (uint16_t *)src;
 
 for (col = 0; col < width; col++)
-*dst_u16++ = dng_raw_to_linear16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
 
 dst += dst_stride * sizeof(uint16_t);
 src += src_stride * sizeof(uint16_t);
@@ -782,7 +794,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 } else {
 for (line = 0; line < height; line++) {
 for (col = 0; col < width; col++)
-*dst++ = dng_raw_to_linear8(*src++, s->dng_lut, 
s->black_level, scale_factor);
+*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
 
 dst += dst_stride;
 src += src_stride;
-- 
2.17.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v15 01/15] lavc/mjpegdec: Decode Huffman-coded lossless JPEGs embedded in DNGs

2019-08-20 Thread Nick Renieris
Main image data in DNGs is usually comprised of tiles, each of which is a 
Huffman-encoded lossless JPEG.

Tested for ljpeg regressions with:
`ffmpeg -f lavfi -i testsrc=d=1 -vcodec ljpeg test.avi`
`ffmpeg test.avi out.avi`
The modified code in ljpeg_decode_rgb_scan runs without issues.

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 52 +--
 libavcodec/mjpegdec.h |  1 +
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index a65bc8df15..6391107f78 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -412,6 +412,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 return AVERROR_PATCHWELCOME;
 }
 
+/* Lossless JPEGs encoded in DNGs are commonly bayer-encoded. They contain 
2
+   interleaved components and the width stored in their SOF3 markers is the
+   width of each one.  We only output a single component, therefore we need
+   to adjust the output image width. */
+if (s->lossless == 1 && nb_components == 2) {
+s->bayer = 1;
+width *= 2;
+}
 
 /* if different size, realloc/alloc picture */
 if (width != s->width || height != s->height || bits != s->bits ||
@@ -488,6 +496,9 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 }
 
 switch (pix_fmt_id) {
+case 0x: /* for bayer-encoded huffman lossless JPEGs embedded 
in DNGs */
+s->avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
+break;
 case 0x1100:
 if (s->rgb)
 s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_BGR24 : 
AV_PIX_FMT_BGR48;
@@ -1041,17 +1052,20 @@ static int handle_rstn(MJpegDecodeContext *s, int 
nb_components)
 return reset;
 }
 
+/* Handles 1 to 4 components */
 static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int 
predictor, int point_transform)
 {
 int i, mb_x, mb_y;
+unsigned width;
 uint16_t (*buffer)[4];
 int left[4], top[4], topleft[4];
 const int linesize = s->linesize[0];
 const int mask = ((1 << s->bits) - 1) << point_transform;
 int resync_mb_y = 0;
 int resync_mb_x = 0;
+int vpred[6];
 
-if (s->nb_components != 3 && s->nb_components != 4)
+if (s->nb_components <= 0 || s->nb_components > 4)
 return AVERROR_INVALIDDATA;
 if (s->v_max != 1 || s->h_max != 1 || !s->lossless)
 return AVERROR_INVALIDDATA;
@@ -1059,8 +1073,15 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 
 s->restart_count = s->restart_interval;
 
-av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size,
-   (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0]));
+if (s->restart_interval == 0)
+s->restart_interval = INT_MAX;
+
+if (s->bayer)
+width = s->mb_width / nb_components; /* Interleaved, width stored is 
the total so need to divide */
+else
+width = s->mb_width;
+
+av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, width * 4 * 
sizeof(s->ljpeg_buffer[0][0]));
 if (!s->ljpeg_buffer)
 return AVERROR(ENOMEM);
 
@@ -1078,7 +1099,12 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 for (i = 0; i < 4; i++)
 top[i] = left[i] = topleft[i] = buffer[0][i];
 
-for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+if ((mb_y * s->width) % s->restart_interval == 0) {
+for (i = 0; i < 6; i++)
+vpred[i] = 1 << (s->bits-1);
+}
+
+for (mb_x = 0; mb_x < width; mb_x++) {
 int modified_predictor = predictor;
 
 if (get_bits_left(&s->gb) < 1) {
@@ -1102,12 +1128,19 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 topleft[i] = top[i];
 top[i] = buffer[mb_x][i];
 
-PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
-
 dc = mjpeg_decode_dc(s, s->dc_index[i]);
 if(dc == 0xF)
 return -1;
 
+if (!s->bayer || mb_x) {
+pred = left[i];
+} else { /* This path runs only for the first line in bayer 
images */
+vpred[i] += dc;
+pred = vpred[i] - dc;
+}
+
+PREDICT(pred, topleft[i], top[i], pred, modified_predictor);
+
 left[i] = buffer[mb_x][i] =
 mask & (pred + (unsigned)(dc * (1 << point_transform)));
 }
@@ -1151,6 +1184,11 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 ptr[3*mb_x + 0] = buffer

[FFmpeg-devel] [PATCH v15 05/15] lavc/jpegtables: Handle multiple mappings to the same value

2019-08-20 Thread Nick Renieris
Some JPEGs [1] have incorrect DHT entries that map 2 codes to
the same value.

The second (last) mapping does not ever actually appear in the
code stream, therefore ignoring any mappings after the first one
fixes this.

Without this, an "mjpeg_decode_dc: bad vlc: 0:0" error is thrown.

In all known files, the 2 codes are mapped to symbol 0 so only
that case is checked.

---

[1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
 https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/jpegtables.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/libavcodec/jpegtables.c b/libavcodec/jpegtables.c
index cbe5523cb4..fa5c6f9fc5 100644
--- a/libavcodec/jpegtables.c
+++ b/libavcodec/jpegtables.c
@@ -130,14 +130,25 @@ void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, 
uint16_t *huff_code,
 {
 int i, j, k,nb, code, sym;
 
-code = 0;
+/* Some badly encoded files [1] map 2 different codes to symbol 0.
+   Only the first one is valid, so we zero-initialize this here and
+   make sure we only set it once (the first time) in the loop below.
+
+   [1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
+https://www.dji.com/gr/zenmuse-x7/info#downloads
+ */
+huff_size[0] = 0;
+
 k = 0;
+code = 0;
 for(i=1;i<=16;i++) {
 nb = bits_table[i];
 for(j=0;jhttps://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 15/15] lavc/tiff: Enable decoding of LinearRaw images

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

"LinearRaw" is a value that the PhotometricInterpretation tag can be set
to on DNG images that contain color information for all channels instead
of being bayer-encoded ("CFA" value).

The DNG decoder is complete enough that we can enable this now.

Sample:
- http://www.rawsamples.ch/raws/nikon/SCANNER_NIKON_LS5000.DNG

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index c927400a40..da8f5b133e 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1495,6 +1495,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
 case TIFF_PHOTOMETRIC_SEPARATED:
 case TIFF_PHOTOMETRIC_YCBCR:
 case TIFF_PHOTOMETRIC_CFA:
+case TIFF_PHOTOMETRIC_LINEAR_RAW: // Used by DNG images
 s->photometric = value;
 break;
 case TIFF_PHOTOMETRIC_ALPHA_MASK:
@@ -1503,7 +1504,6 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
 case TIFF_PHOTOMETRIC_ITU_LAB:
 case TIFF_PHOTOMETRIC_LOG_L:
 case TIFF_PHOTOMETRIC_LOG_LUV:
-case TIFF_PHOTOMETRIC_LINEAR_RAW:
 avpriv_report_missing_feature(s->avctx,
   "PhotometricInterpretation 0x%04X",
   value);
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 14/15] lavc/tiff: Default-initialize WhiteLevel DNG tag value

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

Initialized to `(2 ^ BitsPerSample) - 1` as per the DNG Specification.

Also make sure that `BlackLevel < WhiteLevel`.

This fixes decoding for "X7 CinemaDNG" samples here:
- https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 22 +++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index dfaef1927d..c927400a40 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1775,6 +1775,7 @@ static int decode_frame(AVCodecContext *avctx,
 GetByteContext stripsizes;
 GetByteContext stripdata;
 int retry_for_subifd, retry_for_page;
+int is_dng;
 
 bytestream2_init(&s->gb, avpkt->data, avpkt->size);
 
@@ -1843,6 +1844,10 @@ again:
 goto again;
 }
 
+/* At this point we've decided on which (Sub)IFD to process */
+
+is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+
 for (i = 0; igeotag_count; i++) {
 const char *keyname = get_geokey_name(s->geotags[i].key);
 if (!keyname) {
@@ -1860,10 +1865,22 @@ again:
 }
 }
 
+if (is_dng) {
+if (s->white_level == 0)
+s->white_level = (1 << s->bpp) - 1; /* Default value as per the 
spec */
+
+if (s->white_level <= s->black_level) {
+av_log(avctx, AV_LOG_ERROR, "BlackLevel (%"PRId32") must be less 
than WhiteLevel (%"PRId32")\n",
+s->black_level, s->white_level);
+return AVERROR_INVALIDDATA;
+}
+}
+
 if (!s->is_tiled && !s->strippos && !s->stripoff) {
 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
 return AVERROR_INVALIDDATA;
 }
+
 /* now we have the data and may start decoding */
 if ((ret = init_image(s, &frame)) < 0)
 return ret;
@@ -1895,7 +1912,7 @@ again:
 
 /* Handle DNG images with JPEG-compressed tiles */
 
-if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == TIFF_TYPE_CINEMADNG) 
&& s->is_tiled) {
+if (is_dng && s->is_tiled) {
 if (!s->is_jpeg) {
 avpriv_report_missing_feature(avctx, "DNG uncompressed tiled 
images");
 return AVERROR_PATCHWELCOME;
@@ -2053,8 +2070,7 @@ again:
 FFSWAP(int,  p->linesize[0], p->linesize[1]);
 }
 
-if (s->is_bayer && s->white_level && s->bpp == 16 &&
-!(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)) {
+if (s->is_bayer && s->white_level && s->bpp == 16 && !is_dng) {
 uint16_t *dst = (uint16_t *)p->data[0];
 for (i = 0; i < s->height; i++) {
 for (j = 0; j < s->width; j++)
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 13/15] lavc/tiff: Support DNGs with striped (non-tiled) JPEGs images

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

DNG samples here can now be decoded:
- https://www.photographyblog.com/previews/pentax_k1_photos

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 61 ---
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 61a140fe09..dfaef1927d 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -551,6 +551,8 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, 
int stride,
 return ret;
 }
 
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame);
+
 static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int 
stride,
  const uint8_t *src, int size, int strip_start, 
int lines)
 {
@@ -666,6 +668,17 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 
 is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
 
+/* Decode JPEG-encoded DNGs with strips */
+if (s->compr == TIFF_NEWJPEG && is_dng) {
+if (s->strips > 1) {
+av_log(s->avctx, AV_LOG_ERROR, "More than one DNG JPEG strips 
unsupported\n");
+return AVERROR_PATCHWELCOME;
+}
+if ((ret = dng_decode_strip(s->avctx, p)) < 0)
+return ret;
+return 0;
+}
+
 for (line = 0; line < lines; line++) {
 if (src - ssrc > size) {
 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -860,8 +873,8 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 }
 }
 
-static int dng_decode_jpeg_tile(AVCodecContext *avctx, AVFrame *frame,
-int tile_byte_count, int x, int y, int w, int 
h)
+static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame,
+   int tile_byte_count, int dst_x, int dst_y, int w, 
int h)
 {
 TiffContext *s = avctx->priv_data;
 AVPacket jpkt;
@@ -913,7 +926,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 return AVERROR_PATCHWELCOME;
 }
 
-dst_offset = x + frame->linesize[0] * y / pixel_size;
+dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size;
 dst_data = frame->data[0] + dst_offset * pixel_size;
 src_data = s->jpgframe->data[0];
 
@@ -932,7 +945,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 return 0;
 }
 
-static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame)
+static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, AVPacket 
*avpkt)
 {
 TiffContext *s = avctx->priv_data;
 int tile_idx;
@@ -945,6 +958,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame 
*frame)
 int pos_x = 0, pos_y = 0;
 int ret;
 
+s->jpgframe->width  = s->tile_width;
+s->jpgframe->height = s->tile_length;
+
+s->avctx_mjpeg->width = s->tile_width;
+s->avctx_mjpeg->height = s->tile_length;
+
 has_width_leftover = (s->width % s->tile_width != 0);
 has_height_leftover = (s->height % s->tile_length != 0);
 
@@ -981,7 +1000,7 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame 
*frame)
 bytestream2_seek(&s->gb, tile_offset, SEEK_SET);
 
 /* Decode JPEG tile and copy it in the reference frame */
-ret = dng_decode_jpeg_tile(avctx, frame, tile_byte_count, pos_x, 
pos_y, tile_width, tile_length);
+ret = dng_decode_jpeg(avctx, frame, tile_byte_count, pos_x, pos_y, 
tile_width, tile_length);
 
 if (ret < 0)
 return ret;
@@ -994,30 +1013,24 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 }
 }
 
-return 0;
-}
+/* Frame is ready to be output */
+frame->pict_type = AV_PICTURE_TYPE_I;
+frame->key_frame = 1;
 
-static int dng_decode(AVCodecContext *avctx, AVFrame *frame, AVPacket *avpkt) {
-int ret;
+return avpkt->size;
+}
 
+static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame)
+{
 TiffContext *s = avctx->priv_data;
 
-s->jpgframe->width  = s->tile_width;
-s->jpgframe->height = s->tile_length;
-
-s->avctx_mjpeg->width = s->tile_width;
-s->avctx_mjpeg->height = s->tile_length;
-
-/* Decode all tiles in a frame */
-ret = dng_decode_tiles(avctx, frame);
-if (ret < 0)
-return ret;
+s->jpgframe->width  = s->width;
+s->jpgframe->height = s->height;
 
-/* Frame is ready to be output */
-frame->pict_type = AV_PICTURE_TYPE_I;
-frame->key_frame = 1;
+s->avctx_mjpeg->width = s->width;
+s->avctx_mjpeg->height = s->height;
 
-return avpkt->size;
+return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, 
s->height);
 }
 
 stat

[FFmpeg-devel] [PATCH v16 06/15] lavc/tiff: Fix edge case with full-length/width tiles

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

When the height is equal to the tile length (full-height tile)
after `height % tile_length` is applied with the current code,
it results in the operating tile_length to be 0.  This commit
makes this leftover logic only applies if it's necessary.

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 78b4bd5301..3bf2b3e557 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -887,10 +887,14 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 int tile_byte_count_offset, tile_byte_count;
 int tile_count_x, tile_count_y;
 int tile_width, tile_length;
+int has_width_leftover, has_height_leftover;
 int tile_x = 0, tile_y = 0;
 int pos_x = 0, pos_y = 0;
 int ret;
 
+has_width_leftover = (s->width % s->tile_width != 0);
+has_height_leftover = (s->height % s->tile_length != 0);
+
 /* Calculate tile counts (round up) */
 tile_count_x = (s->width + s->tile_width - 1) / s->tile_width;
 tile_count_y = (s->height + s->tile_length - 1) / s->tile_length;
@@ -900,12 +904,12 @@ static int dng_decode_tiles(AVCodecContext *avctx, 
AVFrame *frame)
 tile_x = tile_idx % tile_count_x;
 tile_y = tile_idx / tile_count_x;
 
-if (tile_x == tile_count_x - 1) // If on the right edge
+if (has_width_leftover && tile_x == tile_count_x - 1) // If on the 
right-most tile
 tile_width = s->width % s->tile_width;
 else
 tile_width = s->tile_width;
 
-if (tile_y == tile_count_y - 1) // If on the bottom edge
+if (has_height_leftover && tile_y == tile_count_y - 1) // If on the 
bottom-most tile
 tile_length = s->height % s->tile_length;
 else
 tile_length = s->tile_length;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 11/15] lavc/tiff: Decode 10-bit and 14-bit DNG images

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

10-bit sample: http://www.rawsamples.ch/raws/phones/RAW_ONEPLUS_ONE-A0001.DNG
14-bit sample: 
https://drive.google.com/open?id=0B4JyRT3Lth5HVndyOTVOdWktM3J4TFEydTk1MnY3RWlpSzVB

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 23 +++
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index d0d045397d..61a140fe09 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -309,14 +309,19 @@ static void av_always_inline horizontal_fill(TiffContext 
*s,
 dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4;
 }
 break;
-case 12: {
- uint16_t *dst16 = (uint16_t *)dst;
- GetBitContext gb;
- init_get_bits8(&gb, src, width);
- for (int i = 0; i < s->width; i++) {
- dst16[i] = get_bits(&gb, 12) << 4;
- }
- }
+case 10:
+case 12:
+case 14: {
+uint16_t *dst16 = (uint16_t *)dst;
+int is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+uint8_t shift = is_dng ? 0 : 16 - bpp;
+GetBitContext gb;
+
+init_get_bits8(&gb, src, width);
+for (int i = 0; i < s->width; i++) {
+dst16[i] = get_bits(&gb, bpp) << shift;
+}
+}
 break;
 default:
 if (usePtr) {
@@ -1067,7 +1072,9 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
 return AVERROR_PATCHWELCOME;
 }
 break;
+case 10101:
 case 10121:
+case 10141:
 switch (AV_RL32(s->pattern)) {
 case 0x02010100:
 s->avctx->pix_fmt = s->le ? AV_PIX_FMT_BAYER_RGGB16LE : 
AV_PIX_FMT_BAYER_RGGB16BE;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 08/15] lavc/tiff: Force DNG pixel data endianness on an edge case

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

This fixes "X7 RAW" and "X7 CinemaDNG" samples here:
- https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 28b8f42edd..b1d4c50e74 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1038,6 +1038,18 @@ static int init_image(TiffContext *s, ThreadFrame *frame)
AV_RL32(s->pattern));
 return AVERROR_PATCHWELCOME;
 }
+/* Force endianness as mentioned in 'DNG Specification: Chapter 3: 
BitsPerSample'
+   NOTE: The spec actually specifies big-endian, not sure why we need 
little-endian, but
+ such images don't work otherwise. Examples are images 
produced by Zenmuse X7. */
+if ((s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)
+&& (s->bpp != 8 && s->bpp != 16 && s->bpp != 32)) {
+switch (s->avctx->pix_fmt) {
+case AV_PIX_FMT_BAYER_RGGB16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_RGGB16LE; break;
+case AV_PIX_FMT_BAYER_BGGR16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_BGGR16LE; break;
+case AV_PIX_FMT_BAYER_GBRG16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_GBRG16LE; break;
+case AV_PIX_FMT_BAYER_GRBG16BE: s->avctx->pix_fmt = 
AV_PIX_FMT_BAYER_GRBG16LE; break;
+}
+}
 break;
 case 10161:
 switch (AV_RL32(s->pattern)) {
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 01/15] lavc/mjpegdec: Decode Huffman-coded lossless JPEGs embedded in DNGs

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

Main image data in DNGs is usually comprised of tiles, each of which is a 
Huffman-encoded lossless JPEG.

Tested for ljpeg regressions with:
`ffmpeg -f lavfi -i testsrc=d=1 -vcodec ljpeg test.avi`
`ffmpeg test.avi out.avi`
The modified code in ljpeg_decode_rgb_scan runs without issues.

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 52 +--
 libavcodec/mjpegdec.h |  1 +
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index a65bc8df15..6391107f78 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -412,6 +412,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 return AVERROR_PATCHWELCOME;
 }
 
+/* Lossless JPEGs encoded in DNGs are commonly bayer-encoded. They contain 
2
+   interleaved components and the width stored in their SOF3 markers is the
+   width of each one.  We only output a single component, therefore we need
+   to adjust the output image width. */
+if (s->lossless == 1 && nb_components == 2) {
+s->bayer = 1;
+width *= 2;
+}
 
 /* if different size, realloc/alloc picture */
 if (width != s->width || height != s->height || bits != s->bits ||
@@ -488,6 +496,9 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 }
 
 switch (pix_fmt_id) {
+case 0x: /* for bayer-encoded huffman lossless JPEGs embedded 
in DNGs */
+s->avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
+break;
 case 0x1100:
 if (s->rgb)
 s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_BGR24 : 
AV_PIX_FMT_BGR48;
@@ -1041,17 +1052,20 @@ static int handle_rstn(MJpegDecodeContext *s, int 
nb_components)
 return reset;
 }
 
+/* Handles 1 to 4 components */
 static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int 
predictor, int point_transform)
 {
 int i, mb_x, mb_y;
+unsigned width;
 uint16_t (*buffer)[4];
 int left[4], top[4], topleft[4];
 const int linesize = s->linesize[0];
 const int mask = ((1 << s->bits) - 1) << point_transform;
 int resync_mb_y = 0;
 int resync_mb_x = 0;
+int vpred[6];
 
-if (s->nb_components != 3 && s->nb_components != 4)
+if (s->nb_components <= 0 || s->nb_components > 4)
 return AVERROR_INVALIDDATA;
 if (s->v_max != 1 || s->h_max != 1 || !s->lossless)
 return AVERROR_INVALIDDATA;
@@ -1059,8 +1073,15 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 
 s->restart_count = s->restart_interval;
 
-av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size,
-   (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0]));
+if (s->restart_interval == 0)
+s->restart_interval = INT_MAX;
+
+if (s->bayer)
+width = s->mb_width / nb_components; /* Interleaved, width stored is 
the total so need to divide */
+else
+width = s->mb_width;
+
+av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, width * 4 * 
sizeof(s->ljpeg_buffer[0][0]));
 if (!s->ljpeg_buffer)
 return AVERROR(ENOMEM);
 
@@ -1078,7 +1099,12 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 for (i = 0; i < 4; i++)
 top[i] = left[i] = topleft[i] = buffer[0][i];
 
-for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+if ((mb_y * s->width) % s->restart_interval == 0) {
+for (i = 0; i < 6; i++)
+vpred[i] = 1 << (s->bits-1);
+}
+
+for (mb_x = 0; mb_x < width; mb_x++) {
 int modified_predictor = predictor;
 
 if (get_bits_left(&s->gb) < 1) {
@@ -1102,12 +1128,19 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 topleft[i] = top[i];
 top[i] = buffer[mb_x][i];
 
-PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
-
 dc = mjpeg_decode_dc(s, s->dc_index[i]);
 if(dc == 0xF)
 return -1;
 
+if (!s->bayer || mb_x) {
+pred = left[i];
+} else { /* This path runs only for the first line in bayer 
images */
+vpred[i] += dc;
+pred = vpred[i] - dc;
+}
+
+PREDICT(pred, topleft[i], top[i], pred, modified_predictor);
+
 left[i] = buffer[mb_x][i] =
 mask & (pred + (unsigned)(dc * (1 << point_transform)));
 }
@@ -1151,6 +1184,11 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 ptr[

[FFmpeg-devel] [PATCH v16 02/15] lavc/tiff: Decode embedded JPEGs in DNG images

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

Used a technique similar to lavc/tdsc.c for invoking the MJPEG decoder.

This commit adds support for:
- DNG tiles
- DNG tile huffman lossless JPEG decoding
- DNG 8-bpp ("packed" as dcraw calls it) decoding
- DNG color scaling [1]
  - LinearizationTable tag
  - BlackLevel tag

[1]: As specified in the DNG Specification - Chapter 5

Signed-off-by: Nick Renieris 
---
 configure   |   1 +
 libavcodec/Makefile |   2 +-
 libavcodec/tiff.c   | 313 +++-
 libavcodec/tiff.h   |   2 +
 4 files changed, 310 insertions(+), 8 deletions(-)

diff --git a/configure b/configure
index 34c2adb4a4..112b84f0ba 100755
--- a/configure
+++ b/configure
@@ -2817,6 +2817,7 @@ tdsc_decoder_deps="zlib"
 tdsc_decoder_select="mjpeg_decoder"
 theora_decoder_select="vp3_decoder"
 thp_decoder_select="mjpeg_decoder"
+tiff_decoder_select="mjpeg_decoder"
 tiff_decoder_suggest="zlib lzma"
 tiff_encoder_suggest="zlib"
 truehd_decoder_select="mlp_parser"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 3cd73fbcc6..f814c69996 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -616,7 +616,7 @@ OBJS-$(CONFIG_TARGA_ENCODER)   += targaenc.o rle.o
 OBJS-$(CONFIG_TARGA_Y216_DECODER)  += targa_y216dec.o
 OBJS-$(CONFIG_TDSC_DECODER)+= tdsc.o
 OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
-OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o 
tiff_common.o
+OBJS-$(CONFIG_TIFF_DECODER)+= tiff.o lzw.o faxcompr.o tiff_data.o 
tiff_common.o mjpegdec.o
 OBJS-$(CONFIG_TIFF_ENCODER)+= tiffenc.o rle.o lzwenc.o tiff_data.o
 OBJS-$(CONFIG_TMV_DECODER) += tmv.o cga_data.o
 OBJS-$(CONFIG_TRUEHD_DECODER)  += mlpdec.o mlpdsp.o
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index c520d7df83..4c6b835afe 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -35,6 +35,7 @@
 
 #include "libavutil/attributes.h"
 #include "libavutil/avstring.h"
+#include "libavutil/error.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/opt.h"
@@ -46,6 +47,7 @@
 #include "mathops.h"
 #include "tiff.h"
 #include "tiff_data.h"
+#include "mjpegdec.h"
 #include "thread.h"
 #include "get_bits.h"
 
@@ -54,6 +56,10 @@ typedef struct TiffContext {
 AVCodecContext *avctx;
 GetByteContext gb;
 
+/* JPEG decoding for DNG */
+AVCodecContext *avctx_mjpeg; // wrapper context for MJPEG
+AVFrame *jpgframe;   // decoded JPEG tile
+
 int get_subimage;
 uint16_t get_page;
 int get_thumbnail;
@@ -76,7 +82,9 @@ typedef struct TiffContext {
 
 int is_bayer;
 uint8_t pattern[4];
+unsigned black_level;
 unsigned white_level;
+const uint16_t *dng_lut; // Pointer to DNG linearization table
 
 uint32_t sub_ifd;
 uint16_t cur_page;
@@ -86,6 +94,14 @@ typedef struct TiffContext {
 int stripsizesoff, stripsize, stripoff, strippos;
 LZWState *lzw;
 
+/* Tile support */
+int is_tiled;
+int tile_byte_counts_offset, tile_offsets_offset;
+int tile_width, tile_length;
+int tile_count;
+
+int is_jpeg;
+
 uint8_t *deinvert_buf;
 int deinvert_buf_size;
 uint8_t *yuv_line;
@@ -257,6 +273,9 @@ static int add_metadata(int count, int type,
 };
 }
 
+static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
+  const uint8_t *src, int src_stride, int 
width, int height, int is_u16);
+
 static void av_always_inline horizontal_fill(TiffContext *s,
  unsigned int bpp, uint8_t* dst,
  int usePtr, const uint8_t *src,
@@ -712,6 +731,204 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 return 0;
 }
 
+/**
+ * Map stored raw sensor values into linear reference values.
+ * See: DNG Specification - Chapter 5
+ */
+static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
+const uint16_t *lut,
+uint16_t black_level,
+float scale_factor) {
+// Lookup table lookup
+if (lut)
+value = lut[value];
+
+// Black level subtraction
+value = av_clip_uint16_c((unsigned)value - black_level);
+
+// Color scaling
+value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
0x));
+
+return value;
+}
+
+static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+const uint16_t *lut,
+uint1

[FFmpeg-devel] [PATCH v16 04/15] lavc/tiff: Apply color scaling to uncompressed DNGs

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 25 -
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index a2102f32b5..dd1295fad6 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -556,6 +556,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 int is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB) &&
  (desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
  desc->nb_components >= 3;
+int is_dng;
 
 if (s->planar)
 width /= s->bppcount;
@@ -657,6 +658,8 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 bytestream2_init(&s->gb, src, size);
 bytestream2_init_writer(&pb, dst, is_yuv ? s->yuv_line_size : (stride * 
lines));
 
+is_dng = (s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG);
+
 for (line = 0; line < lines; line++) {
 if (src - ssrc > size) {
 av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
@@ -679,6 +682,25 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 for (i = 0; i < width; i++)
 dst[i] = ff_reverse[src[i]];
 }
+
+/* Color processing for DNG images with uncompressed strips 
(non-tiled) */
+if (is_dng) {
+int is_u16, pixel_size_bytes, pixel_size_bits;
+
+is_u16 = (s->bpp > 8);
+pixel_size_bits = (is_u16 ? 16 : 8);
+pixel_size_bytes = (is_u16 ? sizeof(uint16_t) : 
sizeof(uint8_t));
+
+dng_blit(s,
+ dst,
+ 0, // no stride, only 1 line
+ dst,
+ 0, // no stride, only 1 line
+ width / pixel_size_bytes * pixel_size_bits / s->bpp * 
s->bppcount, // need to account for [1, 16] bpp
+ 1,
+ is_u16);
+}
+
 src += width;
 break;
 case TIFF_PACKBITS:
@@ -1945,7 +1967,8 @@ again:
 FFSWAP(int,  p->linesize[0], p->linesize[1]);
 }
 
-if (s->is_bayer && s->white_level && s->bpp == 16) {
+if (s->is_bayer && s->white_level && s->bpp == 16 &&
+!(s->tiff_type == TIFF_TYPE_DNG || s->tiff_type == 
TIFF_TYPE_CINEMADNG)) {
 uint16_t *dst = (uint16_t *)p->data[0];
 for (i = 0; i < s->height; i++) {
 for (j = 0; j < s->width; j++)
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 07/15] lavc/tiff: Don't apply strips-related logic to tiled images

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 42 ++
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 3bf2b3e557..28b8f42edd 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1780,7 +1780,7 @@ again:
 }
 }
 
-if (!s->strippos && !s->stripoff) {
+if (!s->is_tiled && !s->strippos && !s->stripoff) {
 av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
 return AVERROR_INVALIDDATA;
 }
@@ -1788,27 +1788,29 @@ again:
 if ((ret = init_image(s, &frame)) < 0)
 return ret;
 
-if (s->strips == 1 && !s->stripsize) {
-av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
-s->stripsize = avpkt->size - s->stripoff;
-}
+if (!s->is_tiled) {
+if (s->strips == 1 && !s->stripsize) {
+av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
+s->stripsize = avpkt->size - s->stripoff;
+}
 
-if (s->stripsizesoff) {
-if (s->stripsizesoff >= (unsigned)avpkt->size)
-return AVERROR_INVALIDDATA;
-bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
- avpkt->size - s->stripsizesoff);
-}
-if (s->strippos) {
-if (s->strippos >= (unsigned)avpkt->size)
-return AVERROR_INVALIDDATA;
-bytestream2_init(&stripdata, avpkt->data + s->strippos,
- avpkt->size - s->strippos);
-}
+if (s->stripsizesoff) {
+if (s->stripsizesoff >= (unsigned)avpkt->size)
+return AVERROR_INVALIDDATA;
+bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
+avpkt->size - s->stripsizesoff);
+}
+if (s->strippos) {
+if (s->strippos >= (unsigned)avpkt->size)
+return AVERROR_INVALIDDATA;
+bytestream2_init(&stripdata, avpkt->data + s->strippos,
+avpkt->size - s->strippos);
+}
 
-if (s->rps <= 0 || s->rps % s->subsampling[1]) {
-av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
-return AVERROR_INVALIDDATA;
+if (s->rps <= 0 || s->rps % s->subsampling[1]) {
+av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
+return AVERROR_INVALIDDATA;
+}
 }
 
 /* Handle DNG images with JPEG-compressed tiles */
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 03/15] lavc/tiff: Convert DNGs to sRGB color space

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 34 +++---
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 4c6b835afe..a2102f32b5 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -731,14 +731,23 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
 return 0;
 }
 
+static float av_always_inline linear_to_srgb(float value) {
+if (value <= 0.0031308)
+return value * 12.92;
+else
+return pow(value * 1.055, 1.0 / 2.4) - 0.055;
+}
+
 /**
- * Map stored raw sensor values into linear reference values.
- * See: DNG Specification - Chapter 5
+ * Map stored raw sensor values into linear reference values (see: DNG 
Specification - Chapter 5)
+ * Then convert to sRGB color space.
  */
-static uint16_t av_always_inline dng_raw_to_linear16(uint16_t value,
-const uint16_t *lut,
-uint16_t black_level,
-float scale_factor) {
+static uint16_t av_always_inline dng_process_color16(uint16_t value,
+ const uint16_t *lut,
+ uint16_t black_level,
+ float scale_factor) {
+float value_norm;
+
 // Lookup table lookup
 if (lut)
 value = lut[value];
@@ -747,16 +756,19 @@ static uint16_t av_always_inline 
dng_raw_to_linear16(uint16_t value,
 value = av_clip_uint16_c((unsigned)value - black_level);
 
 // Color scaling
-value = av_clip_uint16_c((unsigned)(((float)value * scale_factor) * 
0x));
+value_norm = (float)value * scale_factor;
+
+// Color space conversion (sRGB)
+value = av_clip_uint16_c((uint16_t)(linear_to_srgb(value_norm) * 0x));
 
 return value;
 }
 
-static uint16_t av_always_inline dng_raw_to_linear8(uint16_t value,
+static uint16_t av_always_inline dng_process_color8(uint16_t value,
 const uint16_t *lut,
 uint16_t black_level,
 float scale_factor) {
-return dng_raw_to_linear16(value, lut, black_level, scale_factor) >> 8;
+return dng_process_color16(value, lut, black_level, scale_factor) >> 8;
 }
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
@@ -774,7 +786,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 uint16_t *src_u16 = (uint16_t *)src;
 
 for (col = 0; col < width; col++)
-*dst_u16++ = dng_raw_to_linear16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
 
 dst += dst_stride * sizeof(uint16_t);
 src += src_stride * sizeof(uint16_t);
@@ -782,7 +794,7 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 } else {
 for (line = 0; line < height; line++) {
 for (col = 0; col < width; col++)
-*dst++ = dng_raw_to_linear8(*src++, s->dng_lut, 
s->black_level, scale_factor);
+*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
 
 dst += dst_stride;
 src += src_stride;
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 05/15] lavc/jpegtables: Handle multiple mappings to the same value

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

Some JPEGs [1] have incorrect DHT entries that map 2 codes to
the same value.

The second (last) mapping does not ever actually appear in the
code stream, therefore ignoring any mappings after the first one
fixes this.

Without this, an "mjpeg_decode_dc: bad vlc: 0:0" error is thrown.

In all known files, the 2 codes are mapped to symbol 0 so only
that case is checked.

[1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
 https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/jpegtables.c | 17 ++---
 libavcodec/tiff.c   |  6 +++---
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/libavcodec/jpegtables.c b/libavcodec/jpegtables.c
index cbe5523cb4..fa5c6f9fc5 100644
--- a/libavcodec/jpegtables.c
+++ b/libavcodec/jpegtables.c
@@ -130,14 +130,25 @@ void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, 
uint16_t *huff_code,
 {
 int i, j, k,nb, code, sym;
 
-code = 0;
+/* Some badly encoded files [1] map 2 different codes to symbol 0.
+   Only the first one is valid, so we zero-initialize this here and
+   make sure we only set it once (the first time) in the loop below.
+
+   [1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
+https://www.dji.com/gr/zenmuse-x7/info#downloads
+ */
+huff_size[0] = 0;
+
 k = 0;
+code = 0;
 for(i=1;i<=16;i++) {
 nb = bits_table[i];
 for(j=0;jhttps://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 10/15] lavc/tiff: Support decoding of DNGs with single-component JPEGs

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

This enables decoding of DNG images generated by the 'DJI Zenmuse X7'
digital camera
Samples: https://www.dji.com/gr/zenmuse-x7/info#downloads

Signed-off-by: Nick Renieris 
---
 libavcodec/tiff.c | 61 +++
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 511c057734..d0d045397d 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -274,7 +274,8 @@ static int add_metadata(int count, int type,
 }
 
 static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
-  const uint8_t *src, int src_stride, int 
width, int height, int is_u16);
+  const uint8_t *src, int src_stride, int 
width, int height,
+  int is_single_comp, int is_u16);
 
 static void av_always_inline horizontal_fill(TiffContext *s,
  unsigned int bpp, uint8_t* dst,
@@ -698,6 +699,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, 
uint8_t *dst, int strid
  0, // no stride, only 1 line
  width / pixel_size_bytes * pixel_size_bits / s->bpp * 
s->bppcount, // need to account for [1, 16] bpp
  1,
+ 0, // single-component variation is only preset in 
JPEG-encoded DNGs
  is_u16);
 }
 
@@ -795,18 +797,32 @@ static uint16_t av_always_inline 
dng_process_color8(uint16_t value,
 
 static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride,
  const uint8_t *src, int src_stride,
- int width, int height, int is_u16)
+ int width, int height, int is_single_comp, int is_u16)
 {
 int line, col;
 float scale_factor;
 
 scale_factor = 1.0f / (s->white_level - s->black_level);
 
-if (is_u16) {
-for (line = 0; line < height; line++) {
+if (is_single_comp) {
+if (!is_u16)
+return; /* <= 8bpp unsupported */
+
+/* Image is double the width and half the height we need, each row 
comprises 2 rows of the output
+   (split vertically in the middle). */
+for (line = 0; line < height / 2; line++) {
 uint16_t *dst_u16 = (uint16_t *)dst;
 uint16_t *src_u16 = (uint16_t *)src;
 
+/* Blit first half of input row row to initial row of output */
+for (col = 0; col < width; col++)
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+
+/* Advance the destination pointer by a row (source pointer 
remains in the same place) */
+dst += dst_stride * sizeof(uint16_t);
+dst_u16 = (uint16_t *)dst;
+
+/* Blit second half of input row row to next row of output */
 for (col = 0; col < width; col++)
 *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
 
@@ -814,12 +830,27 @@ static void dng_blit(TiffContext *s, uint8_t *dst, int 
dst_stride,
 src += src_stride * sizeof(uint16_t);
 }
 } else {
-for (line = 0; line < height; line++) {
-for (col = 0; col < width; col++)
-*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
+/* Input and output image are the same size and the MJpeg decoder has 
done per-component
+   deinterleaving, so blitting here is straightforward. */
+if (is_u16) {
+for (line = 0; line < height; line++) {
+uint16_t *dst_u16 = (uint16_t *)dst;
+uint16_t *src_u16 = (uint16_t *)src;
+
+for (col = 0; col < width; col++)
+*dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, 
s->black_level, scale_factor);
+
+dst += dst_stride * sizeof(uint16_t);
+src += src_stride * sizeof(uint16_t);
+}
+} else {
+for (line = 0; line < height; line++) {
+for (col = 0; col < width; col++)
+*dst++ = dng_process_color8(*src++, s->dng_lut, 
s->black_level, scale_factor);
 
-dst += dst_stride;
-src += src_stride;
+dst += dst_stride;
+src += src_stride;
+}
 }
 }
 }
@@ -831,7 +862,7 @@ static int dng_decode_jpeg_tile(AVCodecContext *avctx, 
AVFrame *frame,
 AVPacket jpkt;
 uint8_t *dst_data, *src_data;
 uint32_t dst_offset; /* offset from dst buffer in pixels */
-int is_u16, pixel_size;
+int is_single_comp, is_u16, pixel_size;
 int ret;
 
 /* Prepare a packet and send to the MJPEG decoder */
@@ -865,9 +896,18 @@ static int dng_decode_

[FFmpeg-devel] [PATCH v16 09/15] lavc/mjpegdec: Enable decoding of single-component bayer images

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

Also, ensure no false positives when determining DNG bayer images, by
setting them in tiff.c instead of relying on a heuristic.  There's no
way to determine this just from the JPEG data, so we have to pass this
information from outside the MJPEG decoder.

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 32 +---
 libavcodec/tiff.c |  7 +++
 2 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 6391107f78..0a920a7144 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -412,13 +412,17 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 return AVERROR_PATCHWELCOME;
 }
 
-/* Lossless JPEGs encoded in DNGs are commonly bayer-encoded. They contain 
2
-   interleaved components and the width stored in their SOF3 markers is the
-   width of each one.  We only output a single component, therefore we need
-   to adjust the output image width. */
-if (s->lossless == 1 && nb_components == 2) {
-s->bayer = 1;
-width *= 2;
+if (s->bayer) {
+if (nb_components == 2) {
+/* Bayer images embedded in DNGs can contain 2 interleaved 
components and the
+   width stored in their SOF3 markers is the width of each one.  
We only output
+   a single component, therefore we need to adjust the output 
image width.  We
+   handle the deinterleaving (but not the debayering) in this 
file. */
+width *= 2;
+}
+/* They can also contain 1 component, which is double the width and 
half the height
+of the final image (rows are interleaved).  We don't handle the 
decoding in this
+file, but leave that to the TIFF/DNG decoder. */
 }
 
 /* if different size, realloc/alloc picture */
@@ -1184,10 +1188,16 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, 
int nb_components, int p
 ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
 ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
 }
-} else if (s->bayer && nb_components == 2) {
-for (mb_x = 0; mb_x < width; mb_x++) {
-((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
-((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+} else if (s->bayer) {
+if (nb_components == 1) {
+/* Leave decoding to the TIFF/DNG decoder (see comment in 
ff_mjpeg_decode_sof) */
+for (mb_x = 0; mb_x < width; mb_x++)
+((uint16_t*)ptr)[mb_x] = buffer[mb_x][0];
+} else if (nb_components == 2) {
+for (mb_x = 0; mb_x < width; mb_x++) {
+((uint16_t*)ptr)[2*mb_x + 0] = buffer[mb_x][0];
+((uint16_t*)ptr)[2*mb_x + 1] = buffer[mb_x][1];
+}
 }
 } else {
 for(i=0; igb.buffer;
 jpkt.size = tile_byte_count;
 
+if (s->is_bayer) {
+MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data;
+/* We have to set this information here, there is no way to know if a 
given JPEG is a DNG-embedded
+   image or not from its own data (and we need that information when 
decoding it). */
+mjpegdecctx->bayer = 1;
+}
+
 ret = avcodec_send_packet(s->avctx_mjpeg, &jpkt);
 if (ret < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for 
decoding\n");
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH v16 12/15] lavc/mjpegdec: Skip unknown APPx marker on bayer images

2019-08-28 Thread Nick Renieris
From: Nick Renieris 

Samples:
- Embedded JPEG images in the DNG images here:
  https://www.photographyblog.com/previews/pentax_k1_photos

Signed-off-by: Nick Renieris 
---
 libavcodec/mjpegdec.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 0a920a7144..1f2fabe2df 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1807,8 +1807,15 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
 int len, id, i;
 
 len = get_bits(&s->gb, 16);
-if (len < 6)
-return AVERROR_INVALIDDATA;
+if (len < 6) {
+if (s->bayer) {
+// Pentax K-1 (digital camera) JPEG images embedded in DNG images 
contain unknown APP0 markers
+av_log(s->avctx, AV_LOG_WARNING, "skipping APPx (len=%"PRId32") 
for bayer-encoded image\n", len);
+skip_bits(&s->gb, len);
+return 0;
+} else
+return AVERROR_INVALIDDATA;
+}
 if (8 * len > get_bits_left(&s->gb))
 return AVERROR_INVALIDDATA;
 
-- 
2.21.0.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Re: [FFmpeg-devel] [PATCH v16 05/15] lavc/jpegtables: Handle multiple mappings to the same value

2019-08-29 Thread Nick Renieris
Στις Πέμ, 29 Αυγ 2019 στις 4:00 μ.μ., ο/η Michael Niedermayer
 έγραψε:
> This looks unrelated

Messed up when rebasing, will fix in a bit.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

  1   2   >