Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JPEG compression support #83

Open
johnnychen94 opened this issue Jun 27, 2022 · 4 comments
Open

JPEG compression support #83

johnnychen94 opened this issue Jun 27, 2022 · 4 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@johnnychen94
Copy link
Contributor

johnnychen94 commented Jun 27, 2022

I found this "quad-jpeg.tif" from the libtiff test images https://libtiff.gitlab.io/libtiff/images.html

I just put up a draft JpegTurbo version to support abbreviated data stream JuliaIO/JpegTurbo.jl#25, I believe jpeg_decode(table_bytes, data_bytes) should make things doable. I'd be glad to support any JpegTurbo features needed here.

Because ColorTypes doesn't support YCbCr{N0f8}, we might need some special trick to work around this.

quad-jpeg.tif.zip

@tlnagy tlnagy added the enhancement New feature or request label Jun 28, 2022
@tlnagy
Copy link
Owner

tlnagy commented Jun 28, 2022

I don't see myself having the bandwidth this year for this (trying to wrap up my PhD work right now). Happy to review a PR though.

What would be involved with adding YCbCr{N0f8} to colortypes?

@johnnychen94
Copy link
Contributor Author

Oh, I then have to throw myself into another image format then :) I guess that won't happen until Aug.

What would be involved with adding YCbCr{N0f8} to colortypes?

That probably won't fix the problem. -- Which colorspace does JPEG use to compress the data doesn't affect the output type that much, IIUC, libjpeg-turbo always outputs one of Gray, RGB, AGray, ARGB color. Thus we can't use the current interpretation for YCbCr to allocate the output array.

interpretation(::Val{PHOTOMETRIC_YCBCR}) = YCbCr

Is YCbCr used somewhere else?

@tlnagy
Copy link
Owner

tlnagy commented Aug 12, 2022

Sorry for the delay here, but interpretation is only used for the mapping of the reported colorway in the TIFF file to the julia equivalent, e.g. if there are 3 Float64s in a row then are they RGB{Float64}s or HSL{Float64}, etc. So that's the only place I explicitly use the ColorType structs.

I'm assuming this is the error you're talking about?

julia> TiffImages.load("/home/tlnagy/Downloads/libtiffpic/quad-jpeg.tif")
ERROR: TypeError: in YCbCr, in T, expected T<:AbstractFloat, got Type{FixedPointNumbers.N0f8}
Stacktrace:
  [1] getcache(ifd::TiffImages.IFD{UInt32})
    @ TiffImages ~/.julia/packages/TiffImages/P86VX/src/layout.jl:92
  [2] load(tf::TiffFile{UInt32, FileIO.Stream{FileIO.DataFormat{:TIFF}, IOStream, String}}, ifds::Vector{TiffImages.IFD{UInt32}}, ::Nothing; verbose::Bool)
    @ TiffImages ~/.julia/packages/TiffImages/P86VX/src/load.jl:66
  [3] load(tf::TiffFile{UInt32, FileIO.Stream{FileIO.DataFormat{:TIFF}, IOStream, String}}; verbose::Bool, mmap::Bool)
    @ TiffImages ~/.julia/packages/TiffImages/P86VX/src/load.jl:31
  [4] load(io::IOStream; verbose::Bool, mmap::Bool)
    @ TiffImages ~/.julia/packages/TiffImages/P86VX/src/load.jl:16
  [5] #10
    @ ~/.julia/packages/TiffImages/P86VX/src/load.jl:12 [inlined]
  [6] open(f::TiffImages.var"#10#11"{Bool, Bool}, args::String; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Base ./io.jl:330
  [7] open
    @ ./io.jl:328 [inlined]
  [8] #load#9
    @ ~/.julia/packages/TiffImages/P86VX/src/load.jl:11 [inlined]
  [9] load(filepath::String)
    @ TiffImages ~/.julia/packages/TiffImages/P86VX/src/load.jl:11
 [10] top-level scope
    @ REPL[2]:1

Lets look at the first IFD in the TIFF file using TiffImages:

julia> io = open("/home/tlnagy/Downloads/libtiffpic/quad-jpeg.tif")
IOStream(<file /home/tlnagy/Downloads/libtiffpic/quad-jpeg.tif>)

julia> tf = read(io, TiffImages.TiffFile);

julia> ifd = first(tf); # get first ifd

julia> TiffImages.load!(tf, ifd); # load remote data

julia> ifd
IFD, with tags: 
	Tag(IMAGEWIDTH, 512)
	Tag(IMAGELENGTH, 384)
	Tag(BITSPERSAMPLE, UInt16[8, 8, 8])
	Tag(COMPRESSION, COMPRESSION_JPEG)
	Tag(PHOTOMETRIC, 6)
	Tag(STRIPOFFSETS, UInt32[8, 175, 342, 633, 2227, ...])
	Tag(SAMPLESPERPIXEL, 3)
	Tag(ROWSPERSTRIP, 16)
	Tag(STRIPBYTECOUNTS, UInt32[167, 167, 291, 1594, 1456, ...])
	Tag(PLANARCONFIG, 1)
	Tag(XPOSITION, 0x00000001//0x00000000)
	Tag(YPOSITION, 0x00000001//0x00000000)
	Tag(JPEGTABLES, Any[255, 216, 255, 219, 0, ...])
	Tag(REFERENCEBLACKWHITE, Rational{UInt32}[0x00000001//0x00000000, 0x00200000//0x1fe00000, 0x00200000//0x10000000, 0x00200000//0x1fe00000, 0x00200000//0x10000000, ...])

A photometric representation of 6 is, according to https://www.awaresystems.be/imaging/tiff/tifftags/photometricinterpretation.html, equal to YCbCr. Which means that we need to report the final image (after decompression) as YCbCr{N0f8} (BITSPERSAMPLE is 8) so the lack of YCbCr{N0f8} in Julia will prevent us from representing the results faithfully even if decompression support is added.

@MendeBadra
Copy link

MendeBadra commented Jun 19, 2024


Hello! I've been trying to open a large TIFF file using TiffImages.jl, but I encountered this error:

julia> img_path = "/media/jaki-73/HDD/MendePythonTest/Liver Fat WSI/1_20240522130835.tif";
julia> load(img_path)
Errors encountered while load File{DataFormat{:TIFF}, String}("/media/jaki-73/HDD/MendePythonTest/Liver Fat WSI/1_20240522130835.tif").
All errors:
===========================================
TaskFailedException

    nested task error: Compression COMPRESSION_JPEG is not implemented. Please open an issue against TiffImages.jl.

This is followed by a lengthy stack trace.

Additionally, I ran a code snippet similar to the previous comment:

julia> using TiffImages

julia> tf = read(io, TiffImages.TiffFile);

julia> ifd = first(tf)
IFD, with tags: 
    Tag(IMAGEWIDTH, 121600)
    Tag(IMAGELENGTH, 86272)
    Tag(BITSPERSAMPLE, UInt16[8, 8, 8])
    Tag(COMPRESSION, COMPRESSION_JPEG)
    Tag(PHOTOMETRIC, 2)
    Tag(SAMPLESPERPIXEL, 3)
    Tag(ROWSPERSTRIP, 86272)
    Tag(XRESOLUTION, 0x4b000000//0x00200000)
    Tag(YRESOLUTION, 0x4b000000//0x00200000)
    Tag(PLANARCONFIG, 1)
    Tag(TILEWIDTH, 256)
    Tag(TILELENGTH, 256)
    Tag(TILEOFFSETS, REMOTE@4515844682 UInt64[] len=160075)
    Tag(TILEBYTECOUNTS, REMOTE@4517125282 UInt64[] len=160075)
    Tag(JPEGTABLES, REMOTE@4518405882 Any[] len=289)
    Tag(YCBCRSUBSAMPLING, UInt16[2, 2])

julia> TiffImages.load!(tf, ifd)

It seems that TiffImages.jl does not support the JPEG compression method (COMPRESSION_JPEG), which caused the initial error. Could someone confirm if this is correct? If so, when can we expect support for this feature? As a beginner in Julia, I'm not sure about the effort required to implement this, so please forgive me if my question seems naive.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants