'BIts Per Sample / Pixel libtiff vs WIC

TIFF *TiffImage;
uint16 photo, bps, spp, fillorder;
uint32 width,height;
unsigned long stripSize;
unsigned long imageOffset, result;
int stripMax, stripCount;
unsigned char *buffer, tempbyte;
unsigned short *buffer16;
unsigned int *buffer32;
unsigned long bufferSize, count;
bool success = true;
int shiftCount = 0;


//read image to InData
const char *InFileName = fileName.c_str();

if((TiffImage = TIFFOpen(InFileName, "r")) == NULL){
    ErrMsg("Could not open incoming image\n");
    return false;
}
// Check that it is of a type that we support
if(TIFFGetField(TiffImage, TIFFTAG_BITSPERSAMPLE, &bps) == 0) {
   ErrMsg("Either undefined or unsupported number of bits per sample\n");
   return false;
}
TBitPrecision bitPrecision = (TBitPrecision)bps;

char* imageDesc = NULL;
TIFFGetField(TiffImage, TIFFTAG_IMAGEDESCRIPTION, &imageDesc);

// Get actual bit precision for CP Images
if (bps > 8 && bps <= 16)
{
    if (GetCpTiffTag(imageDesc, CP_TIFFTAG_BITPRECISION, (uint32*)&bitPrecision) == true)
    {
        shiftCount = 16 - bitPrecision;
    }
}

In my libtiff implementation I have used 12 bit per pixel image and also 10 bpp it is very easy to set this info in libtiff

I can't find a similar way to do so in WIC

uint16_t photo, bps, spp, fillorder;
uint32_t width,height;
unsigned long stripSize;
unsigned long imageOffset, result;
int stripMax, stripCount;
unsigned char *buffer, tempbyte;
unsigned short *buffer16;
unsigned int *buffer32;
unsigned long bufferSize, count;
bool success = true;
int shiftCount = 0;

 //read image to InData
const char *InFileName = fileName.c_str();
 IWICImagingFactory* piFactory = NULL;

// Create WIC factory
  HRESULT hr = CoCreateInstance(
  CLSID_WICImagingFactory,
  NULL,
  CLSCTX_INPROC_SERVER,
  IID_PPV_ARGS(&piFactory)
);
 // Create a decoder
IWICBitmapDecoder *pIDecoder = NULL;
IWICBitmapFrameDecode *pIDecoderFrame  = NULL;

std::wstring ws;
ws.assign(fileName.begin(), fileName.end());
// get temporary LPCWSTR (pretty safe)
LPCWSTR pcwstr = ws.c_str();

   hr = piFactory->CreateDecoderFromFilename(
   pcwstr,                      // Image to be decoded
   NULL,                            // Do not prefer a particular vendor
   GENERIC_READ,                    // Desired read access to the file
   WICDecodeMetadataCacheOnDemand,  // Cache metadata when needed
   &pIDecoder                        // Pointer to the decoder
   );
      // Retrieve the first bitmap frame.
if (SUCCEEDED(hr))
{
    hr = pIDecoder->GetFrame(0, &pIDecoderFrame);
}
else
{
     ErrMsg("Could not open incoming image\n");
}
return true;

Am I suppose to use EXIF or XMP? how do I find the TIFFTAG's for WIC?



Solution 1:[1]

The DirectXTex library has lots of examples of using WIC from C++.

You need something like:

using Microsoft::WRL::ComPtr;


ComPtr<IWICMetadataQueryReader> metareader;
hr = pIDecoderFrame->GetMetadataQueryReader(metareader.GetAddressOf());
if (SUCCEEDED(hr))
{
    PROPVARIANT value;
    PropVariantInit(&value);

    if (SUCCEEDED(metareader->GetMetadataByName(L"/ifd/{ushort=258}", &value))
        && value.vt == VT_UI2)
    {
        // BitsPerSample is in value.uiVal
    }

    PropVariantClear(&value);    
}

You should get in the habit of using a smart-pointer like ComPtr rather than using raw interface pointers to keep the ref counts correct.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chuck Walbourn