#include <QtGui>
#include "dpx.h"
#include <iostream>
#define UINT_10_TO_8(val) \
(int)(((float)(val & 0x3FF) * (float)(0xFF)) / (float)(0x3FF))
#define DPX_PIXEL_RGB 50
QLabel* LoadDPX()
{
QString strPath = QFileDialog::getOpenFileName(NULL, "Open DPX File",
QDir::homePath(),
"*.dpx",
NULL, 0);
if (strPath.isEmpty())
return NULL;
DPXHeader hdr;
DPXImageHeader imgHdr;
FILE* pf = fopen(strPath.toStdString().c_str(), "r");
if (!pf)
return NULL;
if (!fread(&hdr, sizeof(hdr), 1, pf))
{
std::cerr << "Unable to read DPXHeader\n";
fclose(pf);
return NULL;
}
if (!fread(&imgHdr, sizeof(imgHdr), 1, pf))
{
std::cerr << "Unable to read DPXImageHeader\n";
fclose(pf);
return NULL;
}
// assume 10-bit image
if (imgHdr.img_element[0].bit_size != 10)
{
std::cerr << "Only supports 10-bit DPX\n";
fclose(pf);
return NULL;
}
// and has RGB interleaved format
if (imgHdr.img_element[0].descriptor != DPX_PIXEL_RGB)
{
std::cerr << "Has to be RGB Interleaved (desciptor == "
<< (int)imgHdr.img_element[0].descriptor << ")\n";
fclose(pf);
return NULL;
}
int nCount = imgHdr.img_width * imgHdr.img_height;
size_t read_size = nCount * sizeof(uint32_t);
QImage* pImg = new QImage(imgHdr.img_width,
imgHdr.img_height,
QImage::Format_RGB32);
// Jump to the right place
fseek(pf, hdr.image_offset, SEEK_SET);
if (!fread(pImg->bits(), sizeof(uint32_t), read_size, pf))
{
std::cerr << "Unable to read image data\n";
delete pImg;
fclose(pf);
return NULL;
}
// now, align the bits properly...
uint32_t* pData32 = (uint32_t*)pImg->bits();
uint32_t val32;
for (int i = 0; i < nCount; i++)
{
val32 = *pData32;
if (imgHdr.img_element[0].packing == 1)
{
// 10-bit DPX packed using METHOD A
// 2 bits padding in least significant bits
// get rid of this bits
val32 >>= 2;
}
*pData32++ = UINT_10_TO_8(val32) | (UINT_10_TO_8(val32>>10)<<8) |
(UINT_10_TO_8(val32>>20)<<16) | (0xFF<<24);
}
QLabel* pResult = new QLabel;
pResult->setPixmap(QPixmap::fromImage(*pImg));
return pResult;
}
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QLabel* label = LoadDPX();
if (!label)
return 0;
label->show();
return app.exec();
}