Ejemplo n.º 1
0
static PyObject *idprop_py_from_idp_string(const IDProperty *prop)
{
    if (prop->subtype == IDP_STRING_SUB_BYTE) {
        return PyBytes_FromStringAndSize(IDP_String(prop), prop->len);
    }
    else {
#ifdef USE_STRING_COERCE
        return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1);
#else
        return PyUnicode_FromStringAndSize(IDP_String(prop), prop->len - 1);
#endif
    }
}
Ejemplo n.º 2
0
static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
{
	char name[128];
	char *param;
	const AVOption *rv = NULL;

	PRINT("FFMPEG expert option: %s: ", prop->name);

	BLI_strncpy(name, prop->name, sizeof(name));

	param = strchr(name, ':');

	if (param) {
		*param++ = 0;
	}

	switch (prop->type) {
		case IDP_STRING:
			PRINT("%s.\n", IDP_String(prop));
			av_set_string3(c, prop->name, IDP_String(prop), 1, &rv);
			break;
		case IDP_FLOAT:
			PRINT("%g.\n", IDP_Float(prop));
			rv = av_set_double(c, prop->name, IDP_Float(prop));
			break;
		case IDP_INT:
			PRINT("%d.\n", IDP_Int(prop));

			if (param) {
				if (IDP_Int(prop)) {
					av_set_string3(c, name, param, 1, &rv);
				}
				else {
					return;
				}
			}
			else {
				rv = av_set_int(c, prop->name, IDP_Int(prop));
			}
			break;
	}

	if (!rv) {
		PRINT("ffmpeg-option not supported: %s! Skipping.\n", prop->name);
	}
}
Ejemplo n.º 3
0
void IMB_metadata_foreach(struct ImBuf *ibuf, IMBMetadataForeachCb callback, void *userdata)
{
  if (ibuf->metadata == NULL) {
    return;
  }
  for (IDProperty *prop = ibuf->metadata->data.group.first; prop != NULL; prop = prop->next) {
    callback(prop->name, IDP_String(prop), userdata);
  }
}
Ejemplo n.º 4
0
static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop, AVDictionary **dictionary)
{
	char name[128];
	char *param;

	PRINT("FFMPEG expert option: %s: ", prop->name);

	BLI_strncpy(name, prop->name, sizeof(name));

	param = strchr(name, ':');

	if (param) {
		*param++ = 0;
	}

	switch (prop->type) {
		case IDP_STRING:
			PRINT("%s.\n", IDP_String(prop));
			av_dict_set(dictionary, name, IDP_String(prop), 0);
			break;
		case IDP_FLOAT:
			PRINT("%g.\n", IDP_Float(prop));
			ffmpeg_dict_set_float(dictionary, prop->name, IDP_Float(prop));
			break;
		case IDP_INT:
			PRINT("%d.\n", IDP_Int(prop));

			if (param) {
				if (IDP_Int(prop)) {
					av_dict_set(dictionary, name, param, 0);
				}
				else {
					return;
				}
			}
			else {
				ffmpeg_dict_set_int(dictionary, prop->name, IDP_Int(prop));
			}
			break;
	}
}
Ejemplo n.º 5
0
bool IMB_metadata_get_field(struct IDProperty *metadata,
                            const char *key,
                            char *field,
                            const size_t len)
{
  IDProperty *prop;

  if (metadata == NULL) {
    return false;
  }

  prop = IDP_GetPropertyFromGroup(metadata, key);

  if (prop && prop->type == IDP_STRING) {
    BLI_strncpy(field, IDP_String(prop), len);
    return true;
  }
  return false;
}
Ejemplo n.º 6
0
int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char *str)
{
	AVCodecContext c;
	const AVOption *o = 0;
	const AVOption *p = 0;
	char name_[128];
	char *name;
	char *param;
	IDProperty *prop = NULL;
	
	avcodec_get_context_defaults3(&c, NULL);

	strncpy(name_, str, sizeof(name_));

	name = name_;
	while (*name == ' ') name++;

	param = strchr(name, ':');

	if (!param) {
		param = strchr(name, ' ');
	}
	if (param) {
		*param++ = 0;
		while (*param == ' ') param++;
	}
	
	o = av_opt_find(&c, name, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
	if (!o) {
		PRINT("Ignoring unknown expert option %s\n", str);
		return 0;
	}
	if (param && o->type == AV_OPT_TYPE_CONST) {
		return 0;
	}
	if (param && o->type != AV_OPT_TYPE_CONST && o->unit) {
		p = av_opt_find(&c, param, o->unit, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
		if (p) {
			prop = BKE_ffmpeg_property_add(rd, (char *) type, p, o);
		}
		else {
			PRINT("Ignoring unknown expert option %s\n", str);
		}
	}
	else {
		prop = BKE_ffmpeg_property_add(rd, (char *) type, o, NULL);
	}
		

	if (!prop) {
		return 0;
	}

	if (param && !p) {
		switch (prop->type) {
			case IDP_INT:
				IDP_Int(prop) = atoi(param);
				break;
			case IDP_FLOAT:
				IDP_Float(prop) = atof(param);
				break;
			case IDP_STRING:
				strncpy(IDP_String(prop), param, prop->len);
				break;
		}
	}
	return 1;
}
Ejemplo n.º 7
0
int ffmpeg_property_add_string(RenderData *rd, const char * type, const char * str)
{
	AVCodecContext c;
	const AVOption * o = 0;
	const AVOption * p = 0;
	char name_[128];
	char * name;
	char * param;
	IDProperty * prop;
	
	avcodec_get_context_defaults(&c);

	strncpy(name_, str, sizeof(name_));

	name = name_;
	while (*name == ' ') name++;

	param = strchr(name, ':');

	if (!param) {
		param = strchr(name, ' ');
	}
	if (param) {
		*param++ = 0;
		while (*param == ' ') param++;
	}
	
	o = my_av_find_opt(&c, name, NULL, 0, 0);	
	if (!o) {
		return 0;
	}
	if (param && o->type == FF_OPT_TYPE_CONST) {
		return 0;
	}
	if (param && o->type != FF_OPT_TYPE_CONST && o->unit) {
		p = my_av_find_opt(&c, param, o->unit, 0, 0);	
		prop = ffmpeg_property_add(rd,
			(char*) type, p - c.av_class->option, 
			o - c.av_class->option);
	} else {
		prop = ffmpeg_property_add(rd,
			(char*) type, o - c.av_class->option, 0);
	}
		

	if (!prop) {
		return 0;
	}

	if (param && !p) {
		switch (prop->type) {
		case IDP_INT:
			IDP_Int(prop) = atoi(param);
			break;
		case IDP_FLOAT:
			IDP_Float(prop) = atof(param);
			break;
		case IDP_STRING:
			strncpy(IDP_String(prop), param, prop->len);
			break;
		}
	}
	return 1;
}
Ejemplo n.º 8
0
static void write_jpeg(struct jpeg_compress_struct *cinfo, struct ImBuf *ibuf)
{
	JSAMPLE *buffer = NULL;
	JSAMPROW row_pointer[1];
	uchar *rect;
	int x, y;
	char neogeo[128];
	struct NeoGeo_Word *neogeo_word;
	char *text;

	jpeg_start_compress(cinfo, true);

	strcpy(neogeo, "NeoGeo");
	neogeo_word = (struct NeoGeo_Word *)(neogeo + 6);
	memset(neogeo_word, 0, sizeof(*neogeo_word));
	neogeo_word->quality = ibuf->foptions.quality;
	jpeg_write_marker(cinfo, 0xe1, (JOCTET *) neogeo, 10);
	if (ibuf->metadata) {
		IDProperty *prop;
		/* key + max value + "Blender" */
		text = MEM_mallocN(530, "stamp info read");
		for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
			if (prop->type == IDP_STRING) {
				int text_len;
				if (!strcmp(prop->name, "None")) {
					jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) IDP_String(prop), prop->len + 1);
				}

				/*
				 * The JPEG format don't support a pair "key/value"
				 * like PNG, so we "encode" the stamp in a
				 * single string:
				 * "Blender:key:value"
				 *
				 * The first "Blender" is a simple identify to help
				 * in the read process.
				 */
				text_len = sprintf(text, "Blender:%s:%s", prop->name, IDP_String(prop));
				jpeg_write_marker(cinfo, JPEG_COM, (JOCTET *) text, text_len + 1);
			}
		}
		MEM_freeN(text);
	}

	row_pointer[0] =
	    MEM_mallocN(sizeof(JSAMPLE) *
	                cinfo->input_components *
	                cinfo->image_width, "jpeg row_pointer");

	for (y = ibuf->y - 1; y >= 0; y--) {
		rect = (uchar *) (ibuf->rect + y * ibuf->x);
		buffer = row_pointer[0];

		switch (cinfo->in_color_space) {
			case JCS_RGB:
				for (x = 0; x < ibuf->x; x++) {
					*buffer++ = rect[0];
					*buffer++ = rect[1];
					*buffer++ = rect[2];
					rect += 4;
				}
				break;
			case JCS_GRAYSCALE:
				for (x = 0; x < ibuf->x; x++) {
					*buffer++ = rect[0];
					rect += 4;
				}
				break;
			case JCS_UNKNOWN:
				memcpy(buffer, rect, 4 * ibuf->x);
				break;
			/* default was missing... intentional ? */
			default:
				/* do nothing */
				break;
		}

		jpeg_write_scanlines(cinfo, row_pointer, 1);
	}

	jpeg_finish_compress(cinfo);
	MEM_freeN(row_pointer[0]);
}
Ejemplo n.º 9
0
int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
{
	png_structp png_ptr;
	png_infop info_ptr;

	unsigned char *pixels = NULL;
	unsigned char *from, *to;
	unsigned short *pixels16 = NULL, *to16;
	float *from_float, from_straight[4];
	png_bytepp row_pointers = NULL;
	int i, bytesperpixel, color_type = PNG_COLOR_TYPE_GRAY;
	FILE *fp = NULL;

	bool is_16bit  = (ibuf->foptions.flag & PNG_16BIT) != 0;
	bool has_float = (ibuf->rect_float != NULL);
	int channels_in_float = ibuf->channels ? ibuf->channels : 4;

	float (*chanel_colormanage_cb)(float);
	size_t num_bytes;

	/* use the jpeg quality setting for compression */
	int compression;
	compression = (int)(((float)(ibuf->foptions.quality) / 11.1111f));
	compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression);

	if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
		/* float buffer was managed already, no need in color space conversion */
		chanel_colormanage_cb = channel_colormanage_noop;
	}
	else {
		/* standard linear-to-srgb conversion if float buffer wasn't managed */
		chanel_colormanage_cb = linearrgb_to_srgb;
	}

	/* for prints */
	if (flags & IB_mem)
		name = "<memory>";

	bytesperpixel = (ibuf->planes + 7) >> 3;
	if ((bytesperpixel > 4) || (bytesperpixel == 2)) {
		printf("imb_savepng: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
		return (0);
	}

	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
	                                  NULL, NULL, NULL);
	if (png_ptr == NULL) {
		printf("imb_savepng: Cannot png_create_write_struct for file: '%s'\n", name);
		return 0;
	}

	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL) {
		png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
		printf("imb_savepng: Cannot png_create_info_struct for file: '%s'\n", name);
		return 0;
	}

	if (setjmp(png_jmpbuf(png_ptr))) {
		png_destroy_write_struct(&png_ptr, &info_ptr);
		printf("imb_savepng: Cannot setjmp for file: '%s'\n", name);
		return 0;
	}

	/* copy image data */
	num_bytes = ((size_t)ibuf->x) * ibuf->y * bytesperpixel;
	if (is_16bit)
		pixels16 = MEM_mallocN(num_bytes * sizeof(unsigned short), "png 16bit pixels");
	else
		pixels = MEM_mallocN(num_bytes * sizeof(unsigned char), "png 8bit pixels");

	if (pixels == NULL && pixels16 == NULL) {
		png_destroy_write_struct(&png_ptr, &info_ptr);
		printf("imb_savepng: Cannot allocate pixels array of %dx%d, %d bytes per pixel for file: '%s'\n", ibuf->x, ibuf->y, bytesperpixel, name);
		return 0;
	}

	from = (unsigned char *) ibuf->rect;
	to = pixels;
	from_float = ibuf->rect_float;
	to16 = pixels16;

	switch (bytesperpixel) {
		case 4:
			color_type = PNG_COLOR_TYPE_RGBA;
			if (is_16bit) {
				if (has_float) {
					if (channels_in_float == 4) {
						for (i = ibuf->x * ibuf->y; i > 0; i--) {
							premul_to_straight_v4_v4(from_straight, from_float);
							to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
							to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
							to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
							to16[3] = ftoshort(chanel_colormanage_cb(from_straight[3]));
							to16 += 4; from_float += 4;
						}
					}
					else if (channels_in_float == 3) {
						for (i = ibuf->x * ibuf->y; i > 0; i--) {
							to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
							to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
							to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
							to16[3] = 65535;
							to16 += 4; from_float += 3;
						}
					}
					else {
						for (i = ibuf->x * ibuf->y; i > 0; i--) {
							to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
							to16[2] = to16[1] = to16[0];
							to16[3] = 65535;
							to16 += 4; from_float++;
						}
					}
				}
				else {
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						to16[0] = UPSAMPLE_8_TO_16(from[0]);
						to16[1] = UPSAMPLE_8_TO_16(from[1]);
						to16[2] = UPSAMPLE_8_TO_16(from[2]);
						to16[3] = UPSAMPLE_8_TO_16(from[3]);
						to16 += 4; from += 4;
					}
				}
			}
			else {
				for (i = ibuf->x * ibuf->y; i > 0; i--) {
					to[0] = from[0];
					to[1] = from[1];
					to[2] = from[2];
					to[3] = from[3];
					to += 4; from += 4;
				}
			}
			break;
		case 3:
			color_type = PNG_COLOR_TYPE_RGB;
			if (is_16bit) {
				if (has_float) {
					if (channels_in_float == 4) {
						for (i = ibuf->x * ibuf->y; i > 0; i--) {
							premul_to_straight_v4_v4(from_straight, from_float);
							to16[0] = ftoshort(chanel_colormanage_cb(from_straight[0]));
							to16[1] = ftoshort(chanel_colormanage_cb(from_straight[1]));
							to16[2] = ftoshort(chanel_colormanage_cb(from_straight[2]));
							to16 += 3; from_float += 4;
						}
					}
					else if (channels_in_float == 3) {
						for (i = ibuf->x * ibuf->y; i > 0; i--) {
							to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
							to16[1] = ftoshort(chanel_colormanage_cb(from_float[1]));
							to16[2] = ftoshort(chanel_colormanage_cb(from_float[2]));
							to16 += 3; from_float += 3;
						}
					}
					else {
						for (i = ibuf->x * ibuf->y; i > 0; i--) {
							to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
							to16[2] = to16[1] = to16[0];
							to16 += 3; from_float++;
						}
					}
				}
				else {
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						to16[0] = UPSAMPLE_8_TO_16(from[0]);
						to16[1] = UPSAMPLE_8_TO_16(from[1]);
						to16[2] = UPSAMPLE_8_TO_16(from[2]);
						to16 += 3; from += 4;
					}
				}
			}
			else {
				for (i = ibuf->x * ibuf->y; i > 0; i--) {
					to[0] = from[0];
					to[1] = from[1];
					to[2] = from[2];
					to += 3; from += 4;
				}
			}
			break;
		case 1:
			color_type = PNG_COLOR_TYPE_GRAY;
			if (is_16bit) {
				if (has_float) {
					float rgb[3];
					if (channels_in_float == 4) {
						for (i = ibuf->x * ibuf->y; i > 0; i--) {
							premul_to_straight_v4_v4(from_straight, from_float);
							rgb[0] = chanel_colormanage_cb(from_straight[0]);
							rgb[1] = chanel_colormanage_cb(from_straight[1]);
							rgb[2] = chanel_colormanage_cb(from_straight[2]);
							to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb));
							to16++; from_float += 4;
						}
					}
					else if (channels_in_float == 3) {
						for (i = ibuf->x * ibuf->y; i > 0; i--) {
							rgb[0] = chanel_colormanage_cb(from_float[0]);
							rgb[1] = chanel_colormanage_cb(from_float[1]);
							rgb[2] = chanel_colormanage_cb(from_float[2]);
							to16[0] = ftoshort(IMB_colormanagement_get_luminance(rgb));
							to16++; from_float += 3;
						}
					}
					else {
						for (i = ibuf->x * ibuf->y; i > 0; i--) {
							to16[0] = ftoshort(chanel_colormanage_cb(from_float[0]));
							to16++; from_float++;
						}
					}
				}
				else {
					for (i = ibuf->x * ibuf->y; i > 0; i--) {
						to16[0] = UPSAMPLE_8_TO_16(from[0]);
						to16++; from += 4;
					}
				}
			}
			else {
				for (i = ibuf->x * ibuf->y; i > 0; i--) {
					to[0] = from[0];
					to++; from += 4;
				}
			}
			break;
	}

	if (flags & IB_mem) {
		/* create image in memory */
		imb_addencodedbufferImBuf(ibuf);
		ibuf->encodedsize = 0;

		png_set_write_fn(png_ptr,
		                 (png_voidp) ibuf,
		                 WriteData,
		                 Flush);
	}
	else {
		fp = BLI_fopen(name, "wb");
		if (!fp) {
			png_destroy_write_struct(&png_ptr, &info_ptr);
			if (pixels)
				MEM_freeN(pixels);
			if (pixels16)
				MEM_freeN(pixels16);
			printf("imb_savepng: Cannot open file for writing: '%s'\n", name);
			return 0;
		}
		png_init_io(png_ptr, fp);
	}

#if 0
	png_set_filter(png_ptr, 0,
	               PNG_FILTER_NONE  | PNG_FILTER_VALUE_NONE  |
	               PNG_FILTER_SUB   | PNG_FILTER_VALUE_SUB   |
	               PNG_FILTER_UP    | PNG_FILTER_VALUE_UP    |
	               PNG_FILTER_AVG   | PNG_FILTER_VALUE_AVG   |
	               PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH |
	               PNG_ALL_FILTERS);
#endif

	png_set_compression_level(png_ptr, compression);

	/* png image settings */
	png_set_IHDR(png_ptr,
	             info_ptr,
	             ibuf->x,
	             ibuf->y,
	             is_16bit ? 16 : 8,
	             color_type,
	             PNG_INTERLACE_NONE,
	             PNG_COMPRESSION_TYPE_DEFAULT,
	             PNG_FILTER_TYPE_DEFAULT);

	/* image text info */
	if (ibuf->metadata) {
		png_text *metadata;
		IDProperty *prop;

		int num_text = 0;

		for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
			if (prop->type == IDP_STRING) {
				num_text++;
			}
		}

		metadata = MEM_callocN(num_text * sizeof(png_text), "png_metadata");
		num_text = 0;
		for (prop = ibuf->metadata->data.group.first; prop; prop = prop->next) {
			if (prop->type == IDP_STRING) {
				metadata[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
				metadata[num_text].key = prop->name;
				metadata[num_text].text = IDP_String(prop);
				num_text++;
			}
		}

		png_set_text(png_ptr, info_ptr, metadata, num_text);
		MEM_freeN(metadata);

	}

	if (ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) {
		png_set_pHYs(png_ptr, info_ptr, (unsigned int)(ibuf->ppm[0] + 0.5), (unsigned int)(ibuf->ppm[1] + 0.5), PNG_RESOLUTION_METER);
	}

	/* write the file header information */
	png_write_info(png_ptr, info_ptr);

#ifdef __LITTLE_ENDIAN__
	png_set_swap(png_ptr);
#endif

	/* allocate memory for an array of row-pointers */
	row_pointers = (png_bytepp) MEM_mallocN(ibuf->y * sizeof(png_bytep), "row_pointers");
	if (row_pointers == NULL) {
		printf("imb_savepng: Cannot allocate row-pointers array for file '%s'\n", name);
		png_destroy_write_struct(&png_ptr, &info_ptr);
		if (pixels)
			MEM_freeN(pixels);
		if (pixels16)
			MEM_freeN(pixels16);
		if (fp) {
			fclose(fp);
		}
		return 0;
	}

	/* set the individual row-pointers to point at the correct offsets */
	if (is_16bit) {
		for (i = 0; i < ibuf->y; i++) {
			row_pointers[ibuf->y - 1 - i] = (png_bytep)
			                                ((unsigned short *)pixels16 + (((size_t)i) * ibuf->x) * bytesperpixel);
		}
	}
	else {
		for (i = 0; i < ibuf->y; i++) {
			row_pointers[ibuf->y - 1 - i] = (png_bytep)
			                                ((unsigned char *)pixels + (((size_t)i) * ibuf->x) * bytesperpixel * sizeof(unsigned char));
		}
	}

	/* write out the entire image data in one call */
	png_write_image(png_ptr, row_pointers);

	/* write the additional chunks to the PNG file (not really needed) */
	png_write_end(png_ptr, info_ptr);

	/* clean up */
	if (pixels)
		MEM_freeN(pixels);
	if (pixels16)
		MEM_freeN(pixels16);
	MEM_freeN(row_pointers);
	png_destroy_write_struct(&png_ptr, &info_ptr);

	if (fp) {
		fflush(fp);
		fclose(fp);
	}

	return(1);
}