What is "CCIR601_sampling" in libjpeg? - jpeg

As the title states: Both the jpeg_compress_struct and the jpeg_decompress_struct in libjpeg have a field defined like this:
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
I am having a hard time figuring out what this means, or how it's supposed to be used. If you try to set this flag to true, either for compression or decompression, libjpeg will simply trigger a fatal error with this message:
JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
The "yet" is amusing because it's been this way for 20+ years now, at least back to libjpeg62.
So, what is CCIR601_sampling supposed to do? Is it meant as a user-settable parameter for compression, decompression, or both? Is it stored as part of the file format? And why has it never actually been implemented?

I have asked the libjpeg-turbo maintainer about this on the mailing list (https://groups.google.com/g/libjpeg-turbo-users/c/Aeacg_cq5ms). Here is part of the response:
To the best of my understanding, the libjpeg API and algorithms adhere to the RGB-to-YCbCr conversion formulae specified in CCIR 601 (now ITU-R Recommendation BT.601). The "CCIR601_sampling" field in the libjpeg API is meant to allow for future support of co-sited Cb and Cr samples-- that is, to allow for the sample arrangement used in MPEG-2. That sample arrangement is non-planar and specifies a row of Y samples, then a row of packed Cb/Cr samples, then another row of Y samples, etc.
... Thus, the fact that Rec. 601 sampling isn't implemented in libjpeg v6b means that JPEG files with that sampling arrangement are basically non-existent "in the wild." The JPEG specification supports other features, including a lossless mode, but ultimately, the de facto definition of the "JPEG format" converged to the subset of features implemented by libjpeg v6b (per Tom Lane's original goal.) To this day, that same chicken-and-egg phenomenon means that web browsers don't support arithmetic-coded JPEG files, even though the patent on arithmetic coding expired long ago and libjpeg-turbo supports those files.
... The "CCIR601_sampling" field remains in the API because the API structures are exposed. Thus, removing the field would break backward ABI compatibility, and backward ABI compatibility is one of the primary reasons (performance is the other) why libjpeg-turbo became the preferred open source JPEG library.
In conclusion: CCIR601_sampling was intended as a user-settable parameter to JPEG compression, which would have produced a JPEG file containing "co-sited" CbCr components (both components stored packed together as one "component", instead of remaining two separate Cb and Cr planes). On decompression, jpeg_read_header() should set the field in the structure to indicate that this JPEG is CCIR601 formatted (it is not a user-settable decompression parameter, rather an indicator)
Of course libjpeg did not support this mode, thus no JPEGs exist that use it, so there is no need to support this mode.

Related

Windows Waveform Functions - WAVEOUTCAPS for bitdepths other than 8 and 16

The Microsoft documentation for the WAVEOUTCAPS struct lists a number of formats that an audio device can support:
I do not see any 24-bit variables listed here, although through I have confirmed my sound card is capable of opening a 24-bit output with a call to WaveOutOpen (and playing 24bit audio files through that output).
I'm guessing that Microsoft defined additional variables somewhere for 18/20/24/32/48/64 bit output, but I can't find them. I tried searching on the net and nothing came up, and I tried using Visual Studio to search for variables in my current name space that start with "WAVE_FORMAT_" but did not find any additionally defined formats that way.
Is it possible to check for 4/18/20/24/32/48/64 bit output availability on Windows using the function WaveOutGetDevCap(), or any similar function? If so, how?
waveOutXxx is legacy API you, generally speaking, should not be used nowadays. This API is an emulation layer on top of real audio API and does not have to support 24-bit scenarios which did not exist at the time of waveOutXxx. There are no specific new constants defined for newer formats and there are so many of them that there cannot be a separate bit for every one.
You can compose a WAVEFORMATEX structure that describes your high bitness format (you would typically use WAVEFORMATEXTENSIBLE variant of it) and check it against waveOutOpen function.
Or, rather, use WASAPI and IAudioClient::Initialize, see Rendering a Stream for details and the way WAVEFORMATEX structure is used there.

Is there a binary kind of SVG?

It just seems to me that when writing code for dynamic data visualization, I end up doing the same things over and over in different languages/platforms. Now if I had a cross platform language(which I do) and something like a binary version of SVG, I could make my code target that and use/create interpreters for whatever platform I currently need to use it on.
The reason I don't want SVG is because the plaintext part makes it too slow for my purposes. I could of course just create my own intermediary format but if there is something already out there that's implemented by various things then the less work for me!
Depending on what you mean by “too slow”, the answer varies:
Filesize too large
Officially, the closest thing SVG has to a binary format is SVGZ, which is a gzipped SVG file with the .svgz extension. All conforming SVG viewers should be able to open it. Making one is simple on *nix systems:
gzip yourfile.svg && mv yourfile.svg.gz yourfile.svgz
You could also try Brotli compression, which tends to have smaller filesize at the cost of more compression time.
Including other assets is inefficient
SVG can only bundle bitmaps and other binary data through base64 encoding, which has a fair amount of overhead.
PDF can include “streams” of raw binary data, and is surprisingly efficient when programmatically generated.
Parsing the text data takes too long
This is tricky. PDF and its brother, Encapsulated PostScript, are also old, well-supported vector graphic formats. Unfortunately, they too are also text at their core, with optional compression.
You could try Computer Graphics Metafiles, which can be compiled ahead of time. But I’m unsure how well-supported they are across consumer devices.
From a comment:
Almost nothing about the performance of SVG other than the transmission cost of sending it over a network is down to it being plaintext
No, that's completely wrong. I worked at CSIRO using XML for massive 3D models. GeoScience Australia did a formal study into the parsing speed - parsing floating point numbers from text is relatively expensive for big data sets, compared to reading a 4 or 8 byte binary representation.
I've spent a lot of time optimising my internal binary formats for Touchgram and am now looking at vector art.
One of the techniques you can use is a combination of
variable-length integer coding and
normalising your points to a scale represented by integers, then storing paths as sequences of deltas
That can yield paths where often only 1 or 2 bytes are used per step, as opposed to the typical 12.
Consider a basic line
<polyline class="Connect" points="100,200 100,100" />
I could represent that with 4 bytes instead of 53.
So far, all I've been able to find in binary SVG is this post about a Go project linking to the project description and repo
Adobe Flash SWF files may work. Due to its previous ubiquity, 'players' and libraries were written for many platforms. The specifications were open and license permitting. For simple 2D graphics, earlier, more compatible versions would do fine.
The files are binary and extraordinarily small.

what is the equivalent of the DirectDraw Surface (DDS) format for opengl on linux?

DDS format has been made for directX right ? so it's should be optimized for it and not for openGL I guess.
So, there is another format(s) ? if yes, what format is a good choice ? what reason(s) ?
also, since I'm working on linux, I'm also concerned by making textures on linux. So I need a format who can be imported/exported by gimp.
The DDS format is useful for storing compressed textures. If you store the file in the same compression as it will be stored in the GPU memory, you don't need to decode and re-encode for GPU storage, instead you can just move it directly to memory.
The DDS format is basically used to store S3 Texture Compression data. The internal DDS formats DTX3 and DTX5 are for example S3TC formats that are also supported by OpenGL:
http://www.opengl.org/wiki/S3_Texture_Compression
DDS also can store pre-calculated mipmaps. Again this is a trade-off (larger file size) for reducing loading times, as the mipmaps could also be calculated at loading time.
As you can see, if you have the right code to parse the DDS file, e.g. the payload will be taken in its compressed form and not decoded on the host machine, then it is perfectly fine to use a DDS.
For an alternative, #CoffeeandCode pointed out the KTX format in his answer. These files use a different compression algorithm (see here). The advantage is that this compression is mandatory in newer OpenGL versions, while S3TC compression was always only available as an extension (and has patent problems). I don't know how they compare in quality and if you can expect OpenGL 4.3 on your target platforms.
My Take: If you are targeting recent hardware and OpenGL support (OpenGL ES 3 or OpenGL 4.3), you should use the KTX format and respective texture formats (libktx will generate the texture objects for you). If you need to be able to run on older hardware or happen to already have a lot of DDS data, you should probably stick with DDS for the time being.
There is nothing particularly D3D-"optimized" about DDS.
Once you read the header correctly, the (optionally) pre-compressed data is binary compatible with S3TC. Both DDS and OpenGL's equivalent (KTX) are capable of storing cubemap arrays and mipmaps in a single image file, that is their primary appeal.
With other formats, you may wind up using the driver to compress and/or generate mipmaps, and the driver usually does a poor job quality wise. The drivers are usually designed to do this quickly because they have a lot of textures that need to be compressed / mipmapped. You can use a higher quality mipmap downsample filter / compression implementation offline since the amount of time required to complete is rather unimportant.
The key benefits of DDS / KTX are:
Offline computation of mipmaps
Offline compression
Store all layers of a texture array/cubemap
Doing (1) and (2) offline can both improve image quality and reduce the overhead of loading textures at run-time. (3) is mostly for convenience, but a welcomed one.
I think the closest equivalent to DDS for DirectX is KTX, but even DDS works fine under OpenGL once parsed.

what format of pic can generate mimap in opengl-es

as the title, I used to use .dds, it did work,now I use type of .png, can it generate mipmap? Here functions what I am using: glTexImage2D(…).Or maybe gluBuild2DMipmaps(…) a better choice?
DDS are an image format that contains precalculated mipmaps. As far as quality goes, precalculated mipmaps offer the best quality, since they can be downsampled offline with advanced filter kernels like Lancozs, without having to care about runtime efficiency.
PNG does not contain additional mipmap levels so you have to compute the mipmaps at runtime. You should however not use gluBuild2DMipmaps for this. For one this function is known to exhibit buggy behavior in certain conditions and furthermore it will unconditionally resample all images to power-of-2 dimensions, although since OpenGL-2 non power-of-2 dimensions are perfectly fine for texture images.
Instead you should load the base level image with glTexImage2D(…) and use glGenerateMipmap(…) (available since OpenGL-3) to build the mipmap image pyramid from there. If you don't use OpenGL-3, you can use the SGIS_generate_mipmap extension, if available.
However be advised that online mipmap generation may yield not as good results as offline generation.
Another possible approach would be the use of JPEG2000 images; the nature of JPEG2000 image encoding results in an image pyramid being readily available. OTOH JPEG2000 is very costly to encode and decode.

Writing Color Calibration Data to a TIFF or PNG file

My custom homebrew photography processing software, running on 64 bit Linux/GNU, writes out PNG and TIFF files. These are to be sent to a quality printing shop to be made into fine art. Working with interior designers - it's important to get the colors just right!
The print shops usually have no trouble with TIFF and PNGs made from commercial software such as Photoshop. Even though i have the TIFF 6.0 specs, PNG specs, and other info in hand, it is not clear how to include color calibration data or implement color management system on linux. My files are often rejected as faulty, without sufficient error reports to make fixes.
This has been a nasty problem for a while for many. Even my contacts at the Hollywood postproduction studios are struggling with this issue. One studio even wanted to hire me to take care of their color calibration, thinking i was the expert - but no, i am just as blind and lost as everyone!
Does anyone know of good code examples, detailed technical information, or have any other enlightenment? Or time to switch to pure Apple?
Take a look at LittleCMS
http://www.littlecms.com/
This page has the code for applying it to TIFF
http://www.littlecms.com/newutils.htm
The basic thing you need to know is that Color profile data is something you need to store in the meta-data of the file itself.
There is a consultant called Charles Poynton who specialises in this area. I work for one of the post production studios you mention (albeit in london not hollywood), and have seen him speak on the subject a couple of times. His website contains a lot of the material he presents and you might find something of use there. He also has a book called Digital Video and HDTV Algorithms and Interfaces which is not as heavy as the title might suggest! While these resources might not answer your question directly, it might provide a spring board to other solutions.
More specifically, which libraries are you using to write the png and tif files - you mention they are homebrew, but how custom are they exactly? Postprocessing the images in an image manipulation program (such as ImageMagick or dcraw) might allow you to inject this information into the header more successfully.
Sorry, I don't have any specific answers, but maybe something that will point you a bit further in the right direction...
As a GNU/Linux user, you’ll want to consider DispcalGUI – http://dispcalgui.hoech.net/ – a GNOME-based GUI that centralizes color management, ICC profile management, and (crucially for your case) device calibration. It can talk to well-known pro- and mid-level hardware, e.g, i1, X-Rite, Spyder, etc.
But before you get into that – you say you are generating your files to spec; are you validating your output using a test suite specific to the format in question? If not, here are three to get you started:
imagetestsuite supports the well-known formats: https://code.google.com/p/imagetestsuite/w/list?can=1&q=
The Luminous* test suite is a JIRA plugin, if that’s your thing: https://marketplace.atlassian.com/plugins/com.luminouslead.plugin.jira.testsuite.LuminousTestSuite
FLOSS Decoder implementations often have one you can use, i.e. OpenJPEG – https://code.google.com/p/openjpeg/wiki/TestSuiteDocumentation
But even barring all of those, it seems like your problem is with embedded ICC data – which is two specs in one. First, there’s the host image-file format, and they all handle embedding differently (meaning the ICC data will likely look totally different when embedded in a TIFF than, say, a JPEG or WebP file). Second, there is the ICC spec itself. It is documented here: http://color.org/v4spec.xalter – and you may also want to look at the source for the aforementioned dispcalGUI, which includes a very legible and hackable ICC profile class in Python: http://sourceforge.net/p/dispcalgui/code/HEAD/tree/trunk/dispcalGUI/ICCProfile.py
Full disclosure: I have contributed to that very ICC profile class, to which I just linked in that last ¶
That’s the basics (many of which you have no doubt covered)... beyond that, if you post more information about what exactly is going wrong, I’d be interested to look it over. Good luck with it either way.
* NB. This project is unrelated to the long-standing photography website, “the Luminous Landscape”

Resources