How to determine top-down/bottom-up from WIC decoder? - c++

I'm using WIC (Windows Imaging Component) to decode image files and get access to the pixel data. I'm trying to figure out the pixel order (i.e., bottom-up or top-down).
I use IWICImagingFactory::CreateDecoderFromFileName to create the decoder from which I grab the (first) frame (IWICBitmapFrameDecode). With the frame, I use GetPixelFormat and GetSize to compute a buffer size, and finally I use CopyPixels to get the decoded pixel data into my buffer.
This works fine with a variety of JPEG files, giving me pixel rows in top-down sequence, and the pixels are in BGRX order (GUID_WICPixelFormat32bppBGR).
When I try with GIF files, however, the pixel rows come in bottom-up sequence. The reported pixel format is RGBA (GUID_WICPixelFormat32bppRGBA), but the ground truth shows the channel order is BGRA (with the blue in the low byte of each 32-bit pixel, just like JPEG).
My primary question: Is there a way for me to query the top-down/bottom-up orientation of the pixel data?
I found a similar question that asked about rotation when using JPEG sources, and the answer was to query the EXIF data to know whether the image was rotated. But EXIF isn't used with GIF. So I'm wondering whether I'm supposed to assume that pixels are always bottom-up, except for ones that do have an EXIF orientation that says otherwise. Update 6/25/2020 Nope, the JPEG orientation is neutral and the GIF has no orientation information, yet MS Paint and other programs can open the files in the correct orientation.
My secondary question: What's up with the incorrect channel order (RGB/BGR) from the GIF decoder?
Not only that, the WIC documentation says that the GIF decoder should return indexes into a color table (GUID_WICPixelFormat8bppIndexed) rather than actual pixel values. Is it possible some software on my machine installed its own buggy GIF decoder that supersedes the one that comes with Windows 10?

To query photo orientation for formats that support it you should use System.Photo.Orientation photo metadata policy (or one of file format specific metadata query paths) using IWICMetadataQueryReader interface.
As for GetPixelFormat() reporting "incorrect" pixel format, it is right there in the Remarks section:
The pixel format returned by this method is not necessarily the pixel format the image is stored as. The codec may perform a format conversion from the storage pixel format to an output pixel format.
Native byte order of image bitmaps under Windows is BGRA, so that is what you are getting from the decoder. If you want image in a different format you need to use IWICImagingFactory::CreateFormatConverter() to create a format converter and convert the image data before copying.
Finally, GIF doesn't have orientation metadata because it is always encoded from top to bottom. Most likely reason you are getting a vertically inverted image is because you are reading it directly from the decoder -- try calling CopyPixels() on the converter instead.

Related

OpenGL Reading Pixels from Texture?

I need a way to get the pixels of an already existing texture. Similarly to how D3DTexture's LockRect works with ReadOnly and NoSysLock. Some of my textures are also stored in compressed DXT1/3/5 formats, not entirely sure if that would affect anything. If those formats are simply decoded by Opengl and stored as raw pixels instead of in the compression. So would retrieving the pixels guarantee the same format that was used to set the texture with?
Generally you will want to use a PBO for reading pixels. Here's all the information you need on PBOs, click here
So would retrieving the pixels guarantee the same format that was used
to set the texture with?
It is possible to convert the format and retrieve the pixels at the same time. Look at the format conversion section on the page I linked.

How i can extract PIXEL from DICOM file?

I want to write a script to extract the PixelDATA of a DICOM file using c or c ++, I don't want to use external libraries like dicomsdl... if anyone can help me to write algorithm for extract and show image .
Just extracting the image data under the pixel data is not enough to interpret the DICOM image properly. You will need other attributes from DICOM file such as Rows, Columns, Bit Allocated, Bit Stored, High Bit, Photometric Interpretation, Sample Per Pixel to Number of Frames information just to interpret the raw uncompressed image data. Also, stored image data can be in Little Endian or Big Endian byte order. In addition, image data can be encapsulated or compressed (e.g. compressed using different compression algorithms such as JPEG, JPEG 2000, JPEG LS, RLE etc)) and compressed streams are stored differently than the uncompressed image data. Even the PixelData element can exist in multiple locations in a single DICOM file (e.g. one under the Icon Image Sequence (thumbnail) and one at the top level (actual image).
It can get more complicated when you need to account for Palette Color (segmented vs un-segmented), modality LUT, VOI LUT etc. My recommendation is to use an existing DICOM SDK and there are many open source and commercial SDK available for different platforms and programming environments.

YCbCr input directly from jpeg loader

I need to extract CbCr chroma data from JPEG images, for image analysis. (in C/C++)
As I understand it, the JPEG "raw data" is compressed YCbCr. Am I correct in this assumption? How can I verify this for a given image?
I am currently using TubroJpeg lib. The documentation of tjDecompressToYUV says that it:
Decompress a JPEG image to a YUV planar image. This function
performs JPEG but leaves out the color conversion step, so a
planar YUV is generated instead of an RGB image.
I am a bit confused as to the output of this function. I thought that YUV and YCbCr were slightly different color spaces. Does this mean that for UV chroma I'd need to manipulate the output, and that the output "UV" components are actually CbCr components ?
The JPEG standard has no knowledge of color spaces. It simply compresses color components.
If is the specific file format (e.g. JFIF, EXIF, ADOBE) that specifies the color format. In most cases it is YCbCR. In some cases it is not (some adobe).
This link may explained the confusion
http://en.wikipedia.org/wiki/Yuv#Confusion_with_Y.27CbCr
YUV and YCbCR are similar, but different. If there is no color conversion, I have to believe that they have confused YUV and YCbCr.

Reading Depth map using OpenGL

I have extracted the depth map of 2 images and stored them as .tif file
now I would like to use openGL to join these two images depending on their depth
so I want to read the depth for each image from the .tif file and then use that depth to draw the pixel with the higher depth
to make it more clear the depth map are two images like this
link
so say I have the pervious image and I want to join it with this image
link
my question is how to read this depth from the .tif file
Ok, I'll have a go ;-)
I see the images are just grayscale, so if the "depth" information is just the intensity of the pixel, "joining" them may be just a matter of adding the pixels. This is generally referred to as "blending", but I don't know what else you could mean.
So, you need to;
Read the 2 images into memory
For each pixel (assuming both images the same size):
read the intensity from image A[row,col]
read the intensity from image B[row,col]
write max(A[row,col],B[row,col]) to C[row,col]
Save image C - this is your new "joined" image.
Now OpenGL doesn't have any built-in support for loading/saving images, so you'll need to find a 3rd party library, like FreeImage or similar.
So, that's a lot of work. I wonder if you really want an OpenGL solution or are just assuming OpenGL would be good for graphics work. If the algorithm above is really what you want, you could do it in something like C# in a matter of minutes. It has built-in support for loading (some formats) of image file, and accessing pixels using the Bitmap class. And since your created this images yourself, you may not be bound the the TIFF format.

reading indexed palette image in C++

My platform is Windows. I didn't expect reading indexed palette image to be this difficult in C++. In case you are not familiar with it, it's single channel image but expresses its pixel color with 256 indexed colors called palette.
I was using OpenCV but its imread just converts the file to a 3 channel image so I have no way to save it back to indexed palette image or compare it with another indexed palette image.
I tried to use Bitmap but for some reason, it does not read correct pixel values.
So right now, I am looking for a light library or code to read pixels from indexed palette file.
Using OpenCV to read or write a image from real cameras will lose and change the image information, so I prefer to use gdi+, which is more powerful in dealing with image format problems to solve your problem.
As comments on the question shows, I decided to have two methods, OpenCV for non-indexed-palette images and Bitmap (GDI+) for indexed palette images. Now everything is working perfect.