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 } }
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); } }
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); } }
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; } }
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; }
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; }
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; }
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]); }
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); }