Esempio n. 1
0
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;
}
Esempio n. 2
0
static void fillCineonMainHeader(LogImageFile *cineon, CineonMainHeader *header,
                                 const char *filename, const char *creator)
{
	time_t fileClock;
	struct tm *fileTime;
	int i;

	memset(header, 0, sizeof(CineonMainHeader));

	/* --- File header --- */
	header->fileHeader.magic_num = swap_uint(CINEON_FILE_MAGIC, cineon->isMSB);
	header->fileHeader.offset = swap_uint(cineon->element[0].dataOffset, cineon->isMSB);
	header->fileHeader.gen_hdr_size = swap_uint(sizeof(CineonFileHeader) + sizeof(CineonImageHeader) +
	                                            sizeof(CineonOriginationHeader), cineon->isMSB);
	header->fileHeader.ind_hdr_size = 0;
	header->fileHeader.user_data_size = 0;
	header->fileHeader.file_size = swap_uint(cineon->element[0].dataOffset + cineon->height * getRowLength(cineon->width, cineon->element[0]), cineon->isMSB);
	strcpy(header->fileHeader.version, "v4.5");
	strncpy(header->fileHeader.file_name, filename, 99);
	header->fileHeader.file_name[99] = 0;
	fileClock = time(NULL);
	fileTime = localtime(&fileClock);
	strftime(header->fileHeader.creation_date, 12, "%Y:%m:%d", fileTime);
	strftime(header->fileHeader.creation_time, 12, "%H:%M:%S%Z", fileTime);
	header->fileHeader.creation_time[11] = 0;

	/* --- Image header --- */
	header->imageHeader.orientation = 0;
	header->imageHeader.elements_per_image = cineon->depth;

	for (i = 0; i < 3; i++) {
		header->imageHeader.element[i].descriptor1 = 0;
		header->imageHeader.element[i].descriptor2 = i;
		header->imageHeader.element[i].bits_per_sample = cineon->element[0].bitsPerSample;
		header->imageHeader.element[i].pixels_per_line = swap_uint(cineon->width, cineon->isMSB);
		header->imageHeader.element[i].lines_per_image = swap_uint(cineon->height, cineon->isMSB);
		header->imageHeader.element[i].ref_low_data = swap_uint(cineon->element[0].refLowData, cineon->isMSB);
		header->imageHeader.element[i].ref_low_quantity = swap_float(cineon->element[0].refLowQuantity, cineon->isMSB);
		header->imageHeader.element[i].ref_high_data = swap_uint(cineon->element[0].refHighData, cineon->isMSB);
		header->imageHeader.element[i].ref_high_quantity = swap_float(cineon->element[0].refHighQuantity, cineon->isMSB);
	}

	header->imageHeader.white_point_x = swap_float(0.0f, cineon->isMSB);
	header->imageHeader.white_point_y = swap_float(0.0f, cineon->isMSB);
	header->imageHeader.red_primary_x = swap_float(0.0f, cineon->isMSB);
	header->imageHeader.red_primary_y = swap_float(0.0f, cineon->isMSB);
	header->imageHeader.green_primary_x = swap_float(0.0f, cineon->isMSB);
	header->imageHeader.green_primary_y = swap_float(0.0f, cineon->isMSB);
	header->imageHeader.blue_primary_x = swap_float(0.0f, cineon->isMSB);
	header->imageHeader.blue_primary_y = swap_float(0.0f, cineon->isMSB);
	strncpy(header->imageHeader.label, creator, 199);
	header->imageHeader.label[199] = 0;
	header->imageHeader.interleave = 0;
	header->imageHeader.data_sign = 0;
	header->imageHeader.sense = 0;
	header->imageHeader.line_padding = swap_uint(0, cineon->isMSB);
	header->imageHeader.element_padding = swap_uint(0, cineon->isMSB);

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

		case 1:
			header->imageHeader.packing = 5;
			break;

		case 2:
			header->imageHeader.packing = 6;
			break;
	}

	/* --- Origination header --- */
	/* we leave it blank */

	/* --- Film header --- */
	/* we leave it blank */
}
Esempio n. 3
0
static void fillDpxMainHeader(LogImageFile *dpx, DpxMainHeader *header, const char *filename, const char *creator)
{
	time_t fileClock;
	struct tm *fileTime;

	memset(header, 0, sizeof(DpxMainHeader));

	/* --- File header --- */
	header->fileHeader.magic_num = swap_uint(DPX_FILE_MAGIC, dpx->isMSB);
	header->fileHeader.offset = swap_uint(dpx->element[0].dataOffset, dpx->isMSB);
	strcpy(header->fileHeader.version, "V2.0");
	header->fileHeader.file_size = swap_uint(dpx->element[0].dataOffset + dpx->height * getRowLength(dpx->width, dpx->element[0]), dpx->isMSB);
	header->fileHeader.ditto_key = 0;
	header->fileHeader.gen_hdr_size = swap_uint(sizeof(DpxFileHeader) + sizeof(DpxImageHeader) + sizeof(DpxOrientationHeader), dpx->isMSB);
	header->fileHeader.ind_hdr_size = swap_uint(sizeof(DpxFilmHeader) + sizeof(DpxTelevisionHeader), dpx->isMSB);
	header->fileHeader.user_data_size = DPX_UNDEFINED_U32;
	strncpy(header->fileHeader.file_name, filename, 99);
	header->fileHeader.file_name[99] = 0;
	fileClock = time(NULL);
	fileTime = localtime(&fileClock);
	strftime(header->fileHeader.creation_date, 24, "%Y:%m:%d:%H:%M:%S%Z", fileTime);
	header->fileHeader.creation_date[23] = 0;
	strncpy(header->fileHeader.creator, creator, 99);
	header->fileHeader.creator[99] = 0;
	header->fileHeader.project[0] = 0;
	header->fileHeader.copyright[0] = 0;
	header->fileHeader.key = 0xFFFFFFFF;

	/* --- Image header --- */
	header->imageHeader.orientation = 0;
	header->imageHeader.elements_per_image = swap_ushort(1, dpx->isMSB);
	header->imageHeader.pixels_per_line = swap_uint(dpx->width, dpx->isMSB);
	header->imageHeader.lines_per_element = swap_uint(dpx->height, dpx->isMSB);

	/* Fills element */
	header->imageHeader.element[0].data_sign = 0;
	header->imageHeader.element[0].ref_low_data = swap_uint(dpx->element[0].refLowData, dpx->isMSB);
	header->imageHeader.element[0].ref_low_quantity = swap_float(dpx->element[0].refLowQuantity, dpx->isMSB);
	header->imageHeader.element[0].ref_high_data = swap_uint(dpx->element[0].refHighData, dpx->isMSB);
	header->imageHeader.element[0].ref_high_quantity = swap_float(dpx->element[0].refHighQuantity, dpx->isMSB);
	header->imageHeader.element[0].descriptor = dpx->element[0].descriptor;
	header->imageHeader.element[0].transfer = dpx->element[0].transfer;
	header->imageHeader.element[0].colorimetric = 0;
	header->imageHeader.element[0].bits_per_sample = dpx->element[0].bitsPerSample;
	header->imageHeader.element[0].packing = swap_ushort(dpx->element[0].packing, dpx->isMSB);
	header->imageHeader.element[0].encoding = 0;
	header->imageHeader.element[0].data_offset = swap_uint(dpx->element[0].dataOffset, dpx->isMSB);
	header->imageHeader.element[0].line_padding = 0;
	header->imageHeader.element[0].element_padding = 0;
	header->imageHeader.element[0].description[0] = 0;

	/* --- Orientation header --- */
	/* we leave it blank */

	/* --- Television header --- */
	header->televisionHeader.time_code = DPX_UNDEFINED_U32;
	header->televisionHeader.user_bits = DPX_UNDEFINED_U32;
	header->televisionHeader.interlace = DPX_UNDEFINED_U8;
	header->televisionHeader.field_number = DPX_UNDEFINED_U8;
	header->televisionHeader.video_signal = DPX_UNDEFINED_U8;
	header->televisionHeader.padding = DPX_UNDEFINED_U8;
	header->televisionHeader.horizontal_sample_rate = DPX_UNDEFINED_R32;
	header->televisionHeader.vertical_sample_rate = DPX_UNDEFINED_R32;
	header->televisionHeader.frame_rate = DPX_UNDEFINED_R32;
	header->televisionHeader.time_offset = DPX_UNDEFINED_R32;
	header->televisionHeader.gamma = swap_float(dpx->gamma, dpx->isMSB);
	header->televisionHeader.black_level = swap_float(dpx->referenceBlack, dpx->isMSB);
	header->televisionHeader.black_gain = DPX_UNDEFINED_R32;
	header->televisionHeader.breakpoint = DPX_UNDEFINED_R32;
	header->televisionHeader.white_level = swap_float(dpx->referenceWhite, dpx->isMSB);
	header->televisionHeader.integration_times = DPX_UNDEFINED_R32;
}