Exemple #1
0
int
cineonGetRowBytes(CineonFile* cineon, unsigned short* row, int y) {

	int longsRead;
	int pixelIndex;
	int longIndex;
	int numPixels = cineon->width * cineon->depth;


	/* only seek if not reading consecutive lines */
	if (y != cineon->fileYPos) {
		int lineOffset = cineon->imageOffset + y * cineon->lineBufferLength * 4;
		if (verbose) d_printf("Seek in getRowBytes\n");
		if (logimage_fseek(cineon, lineOffset, SEEK_SET) != 0) {
			if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, lineOffset);
			return 1;
		}
		cineon->fileYPos = y;
	}

	longsRead = logimage_fread(cineon->lineBuffer, 4, cineon->lineBufferLength, cineon);
	if (longsRead != cineon->lineBufferLength) {
		if (verbose) {
			d_printf("Couldn't read line %d length %d\n", y, cineon->lineBufferLength * 4);
			perror("cineonGetRowBytes");
		}

		return 1;
	}

	/* remember where we left the car, honey */
	++cineon->fileYPos;

	/* convert longwords to pixels */
	pixelIndex = 0;
	for (longIndex = 0; longIndex < cineon->lineBufferLength; ++longIndex) {
		unsigned int t = ntohl(cineon->lineBuffer[longIndex]);
		t = t >> 2;
		cineon->pixelBuffer[pixelIndex+2] = (unsigned short) t & 0x3ff;
		t = t >> 10;
		cineon->pixelBuffer[pixelIndex+1] = (unsigned short) t & 0x3ff;
		t = t >> 10;
		cineon->pixelBuffer[pixelIndex] = (unsigned short) t & 0x3ff;
		pixelIndex += 3;
	}

	/* extract required pixels */
	for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
		if (cineon->params.doLogarithm)
			row[pixelIndex] = cineon->lut10_16[cineon->pixelBuffer[pixelIndex]];
		else
			row[pixelIndex] = cineon->pixelBuffer[pixelIndex] << 6;
	}

	return 0;
}
Exemple #2
0
int
dpxGetRowBytes(DpxFile* dpx, unsigned short* row, int y) {

	/* Note: this code is bizarre because DPX files can wrap */
	/* packed longwords across line boundaries!!!! */

	size_t readLongs;
	unsigned int longIndex;
	int numPixels = dpx->width * dpx->depth;
	int pixelIndex;

	/* only seek if not reading consecutive lines */
	/* this is not quite right yet, need to account for leftovers */
	if (y != dpx->fileYPos) {
		int lineOffset = pixelsToLongs(y * dpx->width * dpx->depth) * 4;
		if (verbose) d_printf("Seek in getRowBytes\n");
		if (logimage_fseek(dpx, dpx->imageOffset + lineOffset, SEEK_SET) != 0) {
			if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, dpx->imageOffset + lineOffset);
			return 1;
		}
		dpx->fileYPos = y;
	}

	/* read enough longwords */
	readLongs = pixelsToLongs(numPixels - dpx->pixelBufferUsed);
	if (logimage_fread(dpx->lineBuffer, 4, readLongs, dpx) != readLongs) {
		if (verbose) d_printf("Couldn't read line %d length %d\n", y, (int)readLongs * 4);
		return 1;
	}
	++dpx->fileYPos;

	/* convert longwords to pixels */
	pixelIndex = dpx->pixelBufferUsed;

	/* this is just strange */
	if (dpx->depth == 1) {
		for (longIndex = 0; longIndex < readLongs; ++longIndex) {
			unsigned int t = ntohl(dpx->lineBuffer[longIndex]);
			dpx->pixelBuffer[pixelIndex] = t & 0x3ff;
			t = t >> 10;
			dpx->pixelBuffer[pixelIndex+1] = t & 0x3ff;
			t = t >> 10;
			dpx->pixelBuffer[pixelIndex+2] = t & 0x3ff;
			pixelIndex += 3;
		}
	} else /* if (dpx->depth == 3) */ {
		for (longIndex = 0; longIndex < readLongs; ++longIndex) {
Exemple #3
0
int
cineonGetRow(CineonFile* cineon, unsigned short* row, int y) {

	int longsRead;
	int pixelIndex;
	int longIndex;
/*	int numPixels = cineon->width * cineon->depth;
*/
	/* only seek if not reading consecutive lines */
	if (y != cineon->fileYPos) {
		int lineOffset = cineon->imageOffset + y * cineon->lineBufferLength * 4;
		if (verbose) d_printf("Seek in getRow\n");
		if (logimage_fseek(cineon, lineOffset, SEEK_SET) != 0) {
			if (verbose) d_printf("Couldn't seek to line %d at %d\n", y, lineOffset);
			return 1;
		}
		cineon->fileYPos = y;
	}

	longsRead = logimage_fread(cineon->lineBuffer, 4, cineon->lineBufferLength, cineon);
	if (longsRead != cineon->lineBufferLength) {
		if (verbose) d_printf("Couldn't read line %d length %d\n", y, cineon->lineBufferLength * 4);
		return 1;
	}

	/* remember where we left the car, honey */
	++cineon->fileYPos;

	/* convert longwords to pixels */
	pixelIndex = 0;
	for (longIndex = 0; longIndex < cineon->lineBufferLength; ++longIndex) {
		unsigned int t = ntohl(cineon->lineBuffer[longIndex]);
		t = t >> 2;
		row[pixelIndex+2] = (unsigned short) t & 0x3ff;
		t = t >> 10;
		row[pixelIndex+1] = (unsigned short) t & 0x3ff;
		t = t >> 10;
		row[pixelIndex] = (unsigned short) t & 0x3ff;
		pixelIndex += 3;
	}

	return 0;
}
Exemple #4
0
CineonFile* 
cineonOpenFromMem(unsigned char *mem, unsigned int size) {

	CineonGenericHeader header;
	int i;
	
	CineonFile* cineon = (CineonFile* )malloc(sizeof(CineonFile));
	if (cineon == 0) {
		if (verbose) d_printf("Failed to malloc cineon file structure.\n");
		return 0;
	}

	/* for close routine */
	cineon->file = 0;
	cineon->lineBuffer = 0;
	cineon->pixelBuffer = 0;
	cineon->membuffer = mem;
	cineon->membuffersize = size;
	cineon->memcursor = mem;
	
	cineon->file = 0;
	cineon->reading = 1;
	verbose = 0;
	if (size < sizeof(CineonGenericHeader)) {
		if (verbose) d_printf("Not enough data for header!\n");
		cineonClose(cineon);
		return 0;
	}

	logimage_fread(&header, sizeof(CineonGenericHeader), 1, cineon);

	/* let's assume cineon files are always network order */
	if (header.fileInfo.magic_num != ntohl(CINEON_FILE_MAGIC)) {
		if (verbose) d_printf("Bad magic number %8.8lX in\n", (uintptr_t)ntohl(header.fileInfo.magic_num));

		cineonClose(cineon);
		return 0;
	}

	if (header.formatInfo.packing != 5) {
		if (verbose) d_printf("Can't understand packing %d\n", header.formatInfo.packing);
		cineonClose(cineon);
		return 0;
	}

	cineon->width = ntohl(header.imageInfo.channel[0].pixels_per_line);
	cineon->height = ntohl(header.imageInfo.channel[0].lines_per_image);
	cineon->depth = header.imageInfo.channels_per_image;
	/* cineon->bitsPerPixel = 10; */
	cineon->bitsPerPixel = header.imageInfo.channel[0].bits_per_pixel;
	cineon->imageOffset = ntohl(header.fileInfo.image_offset);

	cineon->lineBufferLength = pixelsToLongs(cineon->width * cineon->depth);
	cineon->lineBuffer = malloc(cineon->lineBufferLength * 4);
	if (cineon->lineBuffer == 0) {
		if (verbose) d_printf("Couldn't malloc line buffer of size %d\n", cineon->lineBufferLength * 4);
		cineonClose(cineon);
		return 0;
	}

	cineon->pixelBuffer = malloc(cineon->lineBufferLength * 3 * sizeof(unsigned short));
	if (cineon->pixelBuffer == 0) {
		if (verbose) d_printf("Couldn't malloc pixel buffer of size %d\n",
				(cineon->width * cineon->depth) * (int)sizeof(unsigned short));
		cineonClose(cineon);
		return 0;
	}
	cineon->pixelBufferUsed = 0;

	i = cineon->imageOffset;
	
	if (logimage_fseek(cineon, cineon->imageOffset, SEEK_SET) != 0) {
		if (verbose) d_printf("Couldn't seek to image data at %d\n", cineon->imageOffset);
		cineonClose(cineon);
		return 0;
	}
	
	cineon->fileYPos = 0;

	logImageGetByteConversionDefaults(&cineon->params);
	setupLut(cineon);

	cineon->getRow = &cineonGetRowBytes;
	cineon->setRow = 0;
	cineon->close = &cineonClose;

	if (verbose) {
		verboseMe(cineon);
	}

	return cineon;
}
LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize)
{
	CineonMainHeader header;
	LogImageFile *cineon = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
	const char *filename = (const char *)byteStuff;
	int i;
	unsigned int dataOffset;

	if (cineon == NULL) {
		if (verbose) printf("Cineon: Failed to malloc cineon file structure.\n");
		return NULL;
	}

	/* zero the header */
	memset(&header, 0, sizeof(CineonMainHeader));

	/* for close routine */
	cineon->file = NULL;

	if (fromMemory == 0) {
		/* byteStuff is then the filename */
		cineon->file = BLI_fopen(filename, "rb");
		if (cineon->file == NULL) {
			if (verbose) printf("Cineon: Failed to open file \"%s\".\n", filename);
			logImageClose(cineon);
			return NULL;
		}
		/* not used in this case */
		cineon->memBuffer = NULL;
		cineon->memCursor = NULL;
		cineon->memBufferSize = 0;
	}
	else {
		cineon->memBuffer = (unsigned char *)byteStuff;
		cineon->memCursor = (unsigned char *)byteStuff;
		cineon->memBufferSize = bufferSize;
	}

	if (logimage_fread(&header, sizeof(header), 1, cineon) == 0) {
		if (verbose) printf("Cineon: Not enough data for header in \"%s\".\n", byteStuff);
		logImageClose(cineon);
		return NULL;
	}

	/* endianness determination */
	if (header.fileHeader.magic_num == swap_uint(CINEON_FILE_MAGIC, 1)) {
		cineon->isMSB = 1;
		if (verbose) printf("Cineon: File is MSB.\n");
	}
	else if (header.fileHeader.magic_num == CINEON_FILE_MAGIC) {
		cineon->isMSB = 0;
		if (verbose) printf("Cineon: File is LSB.\n");
	}
	else {
		if (verbose) printf("Cineon: Bad magic number %lu in \"%s\".\n",
			                (unsigned long)header.fileHeader.magic_num, byteStuff);
		logImageClose(cineon);
		return NULL;
	}

	cineon->width = swap_uint(header.imageHeader.element[0].pixels_per_line, cineon->isMSB);
	cineon->height = swap_uint(header.imageHeader.element[0].lines_per_image, cineon->isMSB);

	if (cineon->width == 0 || cineon->height == 0) {
		if (verbose) printf("Cineon: Wrong image dimension: %dx%d\n", cineon->width, cineon->height);
		logImageClose(cineon);
		return NULL;
	}

	cineon->depth = header.imageHeader.elements_per_image;
	cineon->srcFormat = format_Cineon;

	if (header.imageHeader.interleave == 0)
		cineon->numElements = 1;
	else if (header.imageHeader.interleave == 2)
		cineon->numElements = header.imageHeader.elements_per_image;
	else {
		if (verbose) printf("Cineon: Data interleave not supported: %d\n", header.imageHeader.interleave);
		logImageClose(cineon);
		return NULL;
	}

	if (cineon->depth == 1) {
		/* Grayscale image */
		cineon->element[0].descriptor = descriptor_Luminance;
		cineon->element[0].transfer = transfer_Linear;
		cineon->element[0].depth = 1;
	}
	else if (cineon->depth == 3) {
		/* RGB image */
		if (cineon->numElements == 1) {
			cineon->element[0].descriptor = descriptor_RGB;
			cineon->element[0].transfer = transfer_PrintingDensity;
			cineon->element[0].depth = 3;
		}
		else if (cineon->numElements == 3) {
			cineon->element[0].descriptor = descriptor_Red;
			cineon->element[0].transfer = transfer_PrintingDensity;
			cineon->element[0].depth = 1;
			cineon->element[1].descriptor = descriptor_Green;
			cineon->element[1].transfer = transfer_PrintingDensity;
			cineon->element[1].depth = 1;
			cineon->element[2].descriptor = descriptor_Blue;
			cineon->element[2].transfer = transfer_PrintingDensity;
			cineon->element[2].depth = 1;
		}
	}
	else {
		if (verbose) printf("Cineon: Cineon image depth unsupported: %d\n", cineon->depth);
		logImageClose(cineon);
		return NULL;
	}

	dataOffset = swap_uint(header.fileHeader.offset, cineon->isMSB);

	for (i = 0; i < cineon->numElements; i++) {
		cineon->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
		cineon->element[i].maxValue = powf(2, cineon->element[i].bitsPerSample) - 1.0f;
		cineon->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data, cineon->isMSB);
		cineon->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity, cineon->isMSB);
		cineon->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data, cineon->isMSB);
		cineon->element[i].refHighQuantity = swap_float(header.imageHeader.element[i].ref_high_quantity, cineon->isMSB);

		switch (header.imageHeader.packing) {
			case 0:
				cineon->element[i].packing = 0;
				break;

			case 5:
				cineon->element[i].packing = 1;
				break;

			case 6:
				cineon->element[i].packing = 2;
				break;

			default:
				/* Not supported */
				if (verbose) printf("Cineon: packing unsupported: %d\n", header.imageHeader.packing);
				logImageClose(cineon);
				return NULL;
		}

		if (cineon->element[i].refLowData == CINEON_UNDEFINED_U32)
			cineon->element[i].refLowData = 0;

		if (cineon->element[i].refHighData == CINEON_UNDEFINED_U32)
			cineon->element[i].refHighData = (unsigned int)cineon->element[i].maxValue;

		if (cineon->element[i].refLowQuantity == CINEON_UNDEFINED_R32 || isnan(cineon->element[i].refLowQuantity))
			cineon->element[i].refLowQuantity = 0.0f;

		if (cineon->element[i].refHighQuantity == CINEON_UNDEFINED_R32 || isnan(cineon->element[i].refHighQuantity)) {
			if (cineon->element[i].transfer == transfer_PrintingDensity)
				cineon->element[i].refHighQuantity = 2.048f;
			else
				cineon->element[i].refHighQuantity = cineon->element[i].maxValue;
		}

		cineon->element[i].dataOffset = dataOffset;
		dataOffset += cineon->height * getRowLength(cineon->width, cineon->element[i]);
	}

	cineon->referenceBlack = 95.0f / 1023.0f * cineon->element[0].maxValue;
	cineon->referenceWhite = 685.0f / 1023.0f * cineon->element[0].maxValue;
	cineon->gamma = 1.7f;

	if (verbose) {
		printf("size %d x %d x %d elements\n", cineon->width, cineon->height, cineon->numElements);
		for (i = 0; i < cineon->numElements; i++) {
			printf(" Element %d:\n", i);
			printf("  Bits per sample: %d\n", cineon->element[i].bitsPerSample);
			printf("  Depth: %d\n", cineon->element[i].depth);
			printf("  Transfer characteristics: %d\n", cineon->element[i].transfer);
			printf("  Packing: %d\n", cineon->element[i].packing);
			printf("  Descriptor: %d\n", cineon->element[i].descriptor);
			printf("  Data offset: %u\n", cineon->element[i].dataOffset);
			printf("  Reference low data: %u\n", cineon->element[i].refLowData);
			printf("  Reference low quantity: %f\n", cineon->element[i].refLowQuantity);
			printf("  Reference high data: %u\n", cineon->element[i].refHighData);
			printf("  Reference high quantity: %f\n", cineon->element[i].refHighQuantity);
			printf("\n");
		}

		printf("Gamma: %f\n", cineon->gamma);
		printf("Reference black: %f\n", cineon->referenceBlack);
		printf("Reference white: %f\n", cineon->referenceWhite);
		printf("----------------------------\n");
	}
	return cineon;
}
LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t bufferSize)
{
	DpxMainHeader header;
	LogImageFile *dpx = (LogImageFile *)MEM_mallocN(sizeof(LogImageFile), __func__);
	const char *filename = (const char *)byteStuff;
	int i;

	if (dpx == NULL) {
		if (verbose) printf("DPX: Failed to malloc dpx file structure.\n");
		return NULL;
	}

	/* zero the header */
	memset(&header, 0, sizeof(DpxMainHeader));

	/* for close routine */
	dpx->file = NULL;

	if (fromMemory == 0) {
		/* byteStuff is then the filename */
		dpx->file = BLI_fopen(filename, "rb");
		if (dpx->file == NULL) {
			if (verbose) printf("DPX: Failed to open file \"%s\".\n", filename);
			logImageClose(dpx);
			return NULL;
		}
		/* not used in this case */
		dpx->memBuffer = NULL;
		dpx->memCursor = NULL;
		dpx->memBufferSize = 0;
	}
	else {
		dpx->memBuffer = (unsigned char *)byteStuff;
		dpx->memCursor = (unsigned char *)byteStuff;
		dpx->memBufferSize = bufferSize;
	}

	if (logimage_fread(&header, sizeof(header), 1, dpx) == 0) {
		if (verbose) printf("DPX: Not enough data for header in \"%s\".\n", byteStuff);
		logImageClose(dpx);
		return NULL;
	}

	/* endianness determination */
	if (header.fileHeader.magic_num == swap_uint(DPX_FILE_MAGIC, 1)) {
		dpx->isMSB = 1;
		if (verbose) printf("DPX: File is MSB.\n");
	}
	else if (header.fileHeader.magic_num == DPX_FILE_MAGIC) {
		dpx->isMSB = 0;
		if (verbose) printf("DPX: File is LSB.\n");
	}
	else {
		if (verbose)  {
			printf("DPX: Bad magic number %u in \"%s\".\n",
			       header.fileHeader.magic_num, byteStuff);
		}
		logImageClose(dpx);
		return NULL;
	}

	dpx->srcFormat = format_DPX;
	dpx->numElements = swap_ushort(header.imageHeader.elements_per_image, dpx->isMSB);
	if (dpx->numElements == 0) {
		if (verbose) printf("DPX: Wrong number of elements: %d\n", dpx->numElements);
		logImageClose(dpx);
		return NULL;
	}

	dpx->width = swap_uint(header.imageHeader.pixels_per_line, dpx->isMSB);
	dpx->height = swap_uint(header.imageHeader.lines_per_element, dpx->isMSB);

	if (dpx->width == 0 || dpx->height == 0) {
		if (verbose) printf("DPX: Wrong image dimension: %dx%d\n", dpx->width, dpx->height);
		logImageClose(dpx);
		return NULL;
	}

	dpx->depth = 0;

	for (i = 0; i < dpx->numElements; i++) {
		dpx->element[i].descriptor = header.imageHeader.element[i].descriptor;

		switch (dpx->element[i].descriptor) {
			case descriptor_Red:
			case descriptor_Green:
			case descriptor_Blue:
			case descriptor_Alpha:
			case descriptor_Luminance:
			case descriptor_Chrominance:
				dpx->depth++;
				dpx->element[i].depth = 1;
				break;

			case descriptor_CbYCrY:
				dpx->depth += 2;
				dpx->element[i].depth = 2;
				break;

			case descriptor_RGB:
			case descriptor_CbYCr:
			case descriptor_CbYACrYA:
				dpx->depth += 3;
				dpx->element[i].depth = 3;
				break;

			case descriptor_RGBA:
			case descriptor_ABGR:
			case descriptor_CbYCrA:
				dpx->depth += 4;
				dpx->element[i].depth = 4;
				break;

			case descriptor_Depth:
			case descriptor_Composite:
				/* unsupported */
				break;
		}

		if (dpx->depth == 0 || dpx->depth > 4) {
			if (verbose) printf("DPX: Unsupported image depth: %d\n", dpx->depth);
			logImageClose(dpx);
			return NULL;
		}

		dpx->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
		if (dpx->element[i].bitsPerSample != 1 && dpx->element[i].bitsPerSample != 8 &&
		    dpx->element[i].bitsPerSample != 10 && dpx->element[i].bitsPerSample != 12 &&
		    dpx->element[i].bitsPerSample != 16)
		{
			if (verbose) printf("DPX: Unsupported bitsPerSample for elements %d: %d\n", i, dpx->element[i].bitsPerSample);
			logImageClose(dpx);
			return NULL;
		}

		dpx->element[i].maxValue = powf(2, dpx->element[i].bitsPerSample) - 1.0f;

		dpx->element[i].packing = swap_ushort(header.imageHeader.element[i].packing, dpx->isMSB);
		if (dpx->element[i].packing > 2) {
			if (verbose) printf("DPX: Unsupported packing for element %d: %d\n", i, dpx->element[i].packing);
			logImageClose(dpx);
			return NULL;
		}

		/* Sometimes, the offset is not set correctly in the header */
		dpx->element[i].dataOffset = swap_uint(header.imageHeader.element[i].data_offset, dpx->isMSB);
		if (dpx->element[i].dataOffset == 0 && dpx->numElements == 1)
			dpx->element[i].dataOffset = swap_uint(header.fileHeader.offset, dpx->isMSB);

		if (dpx->element[i].dataOffset == 0) {
			if (verbose) printf("DPX: Image header is corrupted.\n");
			logImageClose(dpx);
			return NULL;
		}

		dpx->element[i].transfer = header.imageHeader.element[i].transfer;

		/* if undefined, assign default */
		dpx->element[i].refLowData = swap_uint(header.imageHeader.element[i].ref_low_data, dpx->isMSB);
		dpx->element[i].refLowQuantity = swap_float(header.imageHeader.element[i].ref_low_quantity, dpx->isMSB);
		dpx->element[i].refHighData = swap_uint(header.imageHeader.element[i].ref_high_data, dpx->isMSB);
		dpx->element[i].refHighQuantity = swap_float(header.imageHeader.element[i].ref_high_quantity, dpx->isMSB);

		switch (dpx->element[i].descriptor) {
			case descriptor_Red:
			case descriptor_Green:
			case descriptor_Blue:
			case descriptor_Alpha:
			case descriptor_RGB:
			case descriptor_RGBA:
			case descriptor_ABGR:
				if (dpx->element[i].refLowData == DPX_UNDEFINED_U32)
					dpx->element[i].refLowData = 0;

				if (dpx->element[i].refHighData == DPX_UNDEFINED_U32)
					dpx->element[i].refHighData = (unsigned int)dpx->element[i].maxValue;

				if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refLowQuantity))
					dpx->element[i].refLowQuantity = 0.0f;

				if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refHighQuantity)) {
					if (dpx->element[i].transfer == transfer_PrintingDensity || dpx->element[i].transfer == transfer_Logarithmic)
						dpx->element[i].refHighQuantity = 2.048f;
					else
						dpx->element[i].refHighQuantity = dpx->element[i].maxValue;
				}

				break;

			case descriptor_Luminance:
			case descriptor_Chrominance:
			case descriptor_CbYCrY:
			case descriptor_CbYCr:
			case descriptor_CbYACrYA:
			case descriptor_CbYCrA:
				if (dpx->element[i].refLowData == DPX_UNDEFINED_U32)
					dpx->element[i].refLowData = 16.0f / 255.0f * dpx->element[i].maxValue;

				if (dpx->element[i].refHighData == DPX_UNDEFINED_U32)
					dpx->element[i].refHighData = 235.0f / 255.0f * dpx->element[i].maxValue;

				if (dpx->element[i].refLowQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refLowQuantity))
					dpx->element[i].refLowQuantity = 0.0f;

				if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refHighQuantity))
					dpx->element[i].refHighQuantity = 0.7f;

				break;

			default:
				break;
		}
	}

	dpx->referenceBlack = swap_float(header.televisionHeader.black_level, dpx->isMSB);
	dpx->referenceWhite = swap_float(header.televisionHeader.white_level, dpx->isMSB);
	dpx->gamma = swap_float(header.televisionHeader.gamma, dpx->isMSB);

	if ((dpx->referenceBlack == DPX_UNDEFINED_R32 || isnan(dpx->referenceBlack)) ||
	    (dpx->referenceWhite == DPX_UNDEFINED_R32 || dpx->referenceWhite <= dpx->referenceBlack || isnan(dpx->referenceWhite)) ||
	    (dpx->gamma == DPX_UNDEFINED_R32 || dpx->gamma <= 0 || isnan(dpx->gamma)))
	{
		dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue;
		dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue;
		dpx->gamma = 1.7f;
	}

	if (verbose) {
		printf("size %d x %d x %d elements\n", dpx->width, dpx->height, dpx->numElements);
		for (i = 0; i < dpx->numElements; i++) {
			printf(" Element %d:\n", i);
			printf("  Bits per sample: %d\n", dpx->element[i].bitsPerSample);
			printf("  Depth: %d\n", dpx->element[i].depth);
			printf("  Transfer characteristics: %d\n", dpx->element[i].transfer);
			printf("  Packing: %d\n", dpx->element[i].packing);
			printf("  Descriptor: %d\n", dpx->element[i].descriptor);
			printf("  Data offset: %d\n", dpx->element[i].dataOffset);
			printf("  Reference low data: %u\n", dpx->element[i].refLowData);
			printf("  Reference low quantity: %f\n", dpx->element[i].refLowQuantity);
			printf("  Reference high data: %u\n", dpx->element[i].refHighData);
			printf("  Reference high quantity: %f\n", dpx->element[i].refHighQuantity);
			printf("\n");
		}

		printf("Gamma: %f\n", dpx->gamma);
		printf("Reference black: %f\n", dpx->referenceBlack);
		printf("Reference white: %f\n", dpx->referenceWhite);
		printf("----------------------------\n");
	}
	return dpx;
}