void OutputSingleLayerOperation::deinitExecution() { if (this->getWidth() * this->getHeight() != 0) { int size = get_datatype_size(this->m_datatype); ImBuf *ibuf = IMB_allocImBuf(this->getWidth(), this->getHeight(), this->m_format->planes, 0); Main *bmain = G.main; /* TODO, have this passed along */ char filename[FILE_MAX]; ibuf->channels = size; ibuf->rect_float = this->m_outputBuffer; ibuf->mall |= IB_rectfloat; ibuf->dither = this->m_rd->dither_intensity; IMB_colormanagement_imbuf_for_write(ibuf, true, false, m_viewSettings, m_displaySettings, this->m_format); BKE_makepicstring(filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format, (this->m_rd->scemode & R_EXTENSION), true); if (0 == BKE_imbuf_write(ibuf, filename, this->m_format)) printf("Cannot save Node File Output to %s\n", filename); else printf("Saved: %s\n", filename); IMB_freeImBuf(ibuf); } this->m_outputBuffer = NULL; this->m_imageInput = NULL; }
void OutputStereoOperation::deinitExecution() { unsigned int width = this->getWidth(); unsigned int height = this->getHeight(); if (width != 0 && height != 0) { void *exrhandle; exrhandle = this->get_handle(this->m_path); float *buf = this->m_outputBuffer; /* populate single EXR channel with view data */ IMB_exr_add_channel(exrhandle, NULL, this->m_name, this->m_viewName, 1, this->m_channels * width * height, buf); this->m_imageInput = NULL; this->m_outputBuffer = NULL; /* create stereo ibuf */ if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) { ImBuf *ibuf[3] = {NULL}; const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME}; Main *bmain = G.main; /* TODO, have this passed along */ char filename[FILE_MAX]; int i; /* get rectf from EXR */ for (i = 0; i < 2; i++) { float *rectf = IMB_exr_channel_rect(exrhandle, NULL, this->m_name, names[i]); ibuf[i] = IMB_allocImBuf(width, height, this->m_format->planes, 0); ibuf[i]->channels = this->m_channels; ibuf[i]->rect_float = rectf; ibuf[i]->mall |= IB_rectfloat; ibuf[i]->dither = this->m_rd->dither_intensity; /* do colormanagement in the individual views, so it doesn't need to do in the stereo */ IMB_colormanagement_imbuf_for_write(ibuf[i], true, false, this->m_viewSettings, this->m_displaySettings, this->m_format); IMB_prepare_write_ImBuf(IMB_isfloat(ibuf[i]), ibuf[i]); } /* create stereo buffer */ ibuf[2] = IMB_stereo3d_ImBuf(this->m_format, ibuf[0], ibuf[1]); BKE_image_path_from_imformat( filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format, (this->m_rd->scemode & R_EXTENSION) != 0, true, NULL); BKE_imbuf_write(ibuf[2], filename, this->m_format); /* imbuf knows which rects are not part of ibuf */ for (i = 0; i < 3; i++) IMB_freeImBuf(ibuf[i]); IMB_exr_close(exrhandle); } } }
static int screenshot_exec(bContext *C, wmOperator *op) { ScreenshotData *scd = op->customdata; bool ok = false; if (scd == NULL) { /* when running exec directly */ screenshot_data_create(C, op); scd = op->customdata; } if (scd) { if (scd->dumprect) { ImBuf *ibuf; char path[FILE_MAX]; RNA_string_get(op->ptr, "filepath", path); BLI_path_abs(path, BKE_main_blendfile_path_from_global()); /* operator ensures the extension */ ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0); ibuf->rect = scd->dumprect; /* crop to show only single editor */ if (!RNA_boolean_get(op->ptr, "full")) { screenshot_crop(ibuf, scd->crop); } if (scd->im_format.planes == R_IMF_PLANES_BW) { /* bw screenshot? - users will notice if it fails! */ IMB_color_to_bw(ibuf); } if (BKE_imbuf_write(ibuf, path, &scd->im_format)) { ok = true; } else { BKE_reportf(op->reports, RPT_ERROR, "Could not write image: %s", strerror(errno)); } IMB_freeImBuf(ibuf); } } screenshot_data_free(op); return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED; }
static void rna_Image_save_render(Image *image, bContext *C, ReportList *reports, const char *path, Scene *scene) { ImBuf *ibuf; if (scene == NULL) { scene = CTX_data_scene(C); } if (scene) { ImageUser iuser; void *lock; iuser.scene = scene; iuser.ok = 1; ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); if (ibuf == NULL) { BKE_report(reports, RPT_ERROR, "Could not acquire buffer from image"); } else { ImBuf *write_ibuf; write_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, true, true, &scene->view_settings, &scene->display_settings, &scene->r.im_format); write_ibuf->planes = scene->r.im_format.planes; write_ibuf->dither = scene->r.dither_intensity; if (!BKE_imbuf_write(write_ibuf, path, &scene->r.im_format)) { BKE_reportf(reports, RPT_ERROR, "Could not write image '%s'", path); } if (write_ibuf != ibuf) IMB_freeImBuf(write_ibuf); } BKE_image_release_ibuf(image, ibuf, lock); } else { BKE_report(reports, RPT_ERROR, "Scene not in context, could not get save parameters"); } }
static int screenshot_exec(bContext *C, wmOperator *op) { ScreenshotData *scd = op->customdata; if (scd == NULL) { /* when running exec directly */ screenshot_data_create(C, op); scd = op->customdata; } if (scd) { if (scd->dumprect) { ImBuf *ibuf; char path[FILE_MAX]; RNA_string_get(op->ptr, "filepath", path); BLI_path_abs(path, G.main->name); /* operator ensures the extension */ ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0); ibuf->rect = scd->dumprect; /* crop to show only single editor */ if (!RNA_boolean_get(op->ptr, "full")) screenshot_crop(ibuf, scd->crop); if (scd->im_format.planes == R_IMF_PLANES_BW) { /* bw screenshot? - users will notice if it fails! */ IMB_color_to_bw(ibuf); } BKE_imbuf_write(ibuf, path, &scd->im_format); IMB_freeImBuf(ibuf); } } screenshot_data_free(op); return OPERATOR_FINISHED; }
static bool write_external_bake_pixels( const char *filepath, BakePixel pixel_array[], float *buffer, const int width, const int height, const int margin, ImageFormatData *im_format, const bool is_noncolor) { ImBuf *ibuf = NULL; bool ok = false; bool is_float; is_float = im_format->depth > 8; /* create a new ImBuf */ ibuf = IMB_allocImBuf(width, height, im_format->planes, (is_float ? IB_rectfloat : IB_rect)); if (!ibuf) return false; /* populates the ImBuf */ if (is_float) { IMB_buffer_float_from_float( ibuf->rect_float, buffer, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false, ibuf->x, ibuf->y, ibuf->x, ibuf->x); } else { if (!is_noncolor) { const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR); const char *to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf); IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false); } IMB_buffer_byte_from_float( (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, false, ibuf->x, ibuf->y, ibuf->x, ibuf->x); } /* margins */ if (margin > 0) { char *mask_buffer = NULL; const size_t num_pixels = (size_t)width * (size_t)height; mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask"); RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer); RE_bake_margin(ibuf, mask_buffer, margin); if (mask_buffer) MEM_freeN(mask_buffer); } if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) { #ifndef WIN32 chmod(filepath, S_IRUSR | S_IWUSR); #endif //printf("%s saving bake map: '%s'\n", __func__, filepath); } /* garbage collection */ IMB_freeImBuf(ibuf); return ok; }
/* only this runs inside thread */ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float *UNUSED(progress)) { ScreenshotJob *sj = sjv; RenderData rd = sj->scene->r; bMovieHandle *mh = BKE_movie_handle_get(sj->scene->r.im_format.imtype); /* we need this as local variables for renderdata */ rd.frs_sec = U.scrcastfps; rd.frs_sec_base = 1.0f; if (BKE_imtype_is_movie(rd.im_format.imtype)) { if (!mh->start_movie(sj->scene, &rd, sj->dumpsx, sj->dumpsy, &sj->reports)) { printf("screencast job stopped\n"); return; } } else mh = NULL; sj->stop = stop; sj->do_update = do_update; *do_update = true; /* wait for opengl rect */ while (*stop == 0) { if (sj->dumprect) { if (mh) { if (mh->append_movie(&rd, rd.sfra, rd.cfra, (int *)sj->dumprect, sj->dumpsx, sj->dumpsy, &sj->reports)) { BKE_reportf(&sj->reports, RPT_INFO, "Appended frame: %d", rd.cfra); printf("Appended frame %d\n", rd.cfra); } else { break; } } else { ImBuf *ibuf = IMB_allocImBuf(sj->dumpsx, sj->dumpsy, rd.im_format.planes, 0); char name[FILE_MAX]; int ok; BKE_makepicstring(name, rd.pic, sj->bmain->name, rd.cfra, &rd.im_format, (rd.scemode & R_EXTENSION) != 0, true); ibuf->rect = sj->dumprect; ok = BKE_imbuf_write(ibuf, name, &rd.im_format); if (ok == 0) { printf("Write error: cannot save %s\n", name); BKE_reportf(&sj->reports, RPT_INFO, "Write error: cannot save %s", name); break; } else { printf("Saved file: %s\n", name); BKE_reportf(&sj->reports, RPT_INFO, "Saved file: %s", name); } /* imbuf knows which rects are not part of ibuf */ IMB_freeImBuf(ibuf); } MEM_freeN(sj->dumprect); sj->dumprect = NULL; *do_update = true; rd.cfra++; } else PIL_sleep_ms(U.scrcastwait); } if (mh) mh->end_movie(); BKE_report(&sj->reports, RPT_INFO, "Screencast job stopped"); }
void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel), void *update_cb_data) { /* note: some of these values remain uninitialized unless certain options * are enabled, take care that BKE_ocean_eval_ij() initializes a member * before use - campbell */ OceanResult ocr; ImageFormatData imf = {0}; int f, i = 0, x, y, cancel = 0; float progress; ImBuf *ibuf_foam, *ibuf_disp, *ibuf_normal; float *prev_foam; int res_x = och->resolution_x; int res_y = och->resolution_y; char string[FILE_MAX]; if (!o) return; if (o->_do_jacobian) prev_foam = MEM_callocN(res_x * res_y * sizeof(float), "previous frame foam bake data"); else prev_foam = NULL; BLI_srand(0); /* setup image format */ imf.imtype = R_IMF_IMTYPE_OPENEXR; imf.depth = R_IMF_CHAN_DEPTH_16; imf.exr_codec = R_IMF_EXR_CODEC_ZIP; for (f = och->start, i = 0; f <= och->end; f++, i++) { /* create a new imbuf to store image for this frame */ ibuf_foam = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat); ibuf_disp = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat); ibuf_normal = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat); BKE_simulate_ocean(o, och->time[i], och->wave_scale, och->chop_amount); /* add new foam */ for (y = 0; y < res_y; y++) { for (x = 0; x < res_x; x++) { BKE_ocean_eval_ij(o, &ocr, x, y); /* add to the image */ rgb_to_rgba_unit_alpha(&ibuf_disp->rect_float[4 * (res_x * y + x)], ocr.disp); if (o->_do_jacobian) { /* TODO, cleanup unused code - campbell */ float /*r, */ /* UNUSED */ pr = 0.0f, foam_result; float neg_disp, neg_eplus; ocr.foam = BKE_ocean_jminus_to_foam(ocr.Jminus, och->foam_coverage); /* accumulate previous value for this cell */ if (i > 0) { pr = prev_foam[res_x * y + x]; } /* r = BLI_frand(); */ /* UNUSED */ /* randomly reduce foam */ /* pr = pr * och->foam_fade; */ /* overall fade */ /* remember ocean coord sys is Y up! * break up the foam where height (Y) is low (wave valley), and X and Z displacement is greatest */ #if 0 vec[0] = ocr.disp[0]; vec[1] = ocr.disp[2]; hor_stretch = len_v2(vec); CLAMP(hor_stretch, 0.0, 1.0); #endif neg_disp = ocr.disp[1] < 0.0f ? 1.0f + ocr.disp[1] : 1.0f; neg_disp = neg_disp < 0.0f ? 0.0f : neg_disp; /* foam, 'ocr.Eplus' only initialized with do_jacobian */ neg_eplus = ocr.Eplus[2] < 0.0f ? 1.0f + ocr.Eplus[2] : 1.0f; neg_eplus = neg_eplus < 0.0f ? 0.0f : neg_eplus; #if 0 if (ocr.disp[1] < 0.0 || r > och->foam_fade) pr *= och->foam_fade; pr = pr * (1.0 - hor_stretch) * ocr.disp[1]; pr = pr * neg_disp * neg_eplus; #endif if (pr < 1.0f) pr *= pr; pr *= och->foam_fade * (0.75f + neg_eplus * 0.25f); /* A full clamping should not be needed! */ foam_result = min_ff(pr + ocr.foam, 1.0f); prev_foam[res_x * y + x] = foam_result; /*foam_result = min_ff(foam_result, 1.0f); */ value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result); } if (o->_do_normals) { rgb_to_rgba_unit_alpha(&ibuf_normal->rect_float[4 * (res_x * y + x)], ocr.normal); } } } /* write the images */ cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_DISPLACE); if (0 == BKE_imbuf_write(ibuf_disp, string, &imf)) printf("Cannot save Displacement File Output to %s\n", string); if (o->_do_jacobian) { cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_FOAM); if (0 == BKE_imbuf_write(ibuf_foam, string, &imf)) printf("Cannot save Foam File Output to %s\n", string); } if (o->_do_normals) { cache_filename(string, och->bakepath, och->relbase, f, CACHE_TYPE_NORMAL); if (0 == BKE_imbuf_write(ibuf_normal, string, &imf)) printf("Cannot save Normal File Output to %s\n", string); } IMB_freeImBuf(ibuf_disp); IMB_freeImBuf(ibuf_foam); IMB_freeImBuf(ibuf_normal); progress = (f - och->start) / (float)och->duration; update_cb(update_cb_data, progress, &cancel); if (cancel) { if (prev_foam) MEM_freeN(prev_foam); return; } } if (prev_foam) MEM_freeN(prev_foam); och->baked = 1; }
/* write input data into individual files */ static void exec_output_file_singlelayer(RenderData *rd, bNode *node, bNodeStack **in) { Main *bmain= G.main; /* TODO, have this passed along */ NodeImageMultiFile *nimf= node->storage; bNodeSocket *sock; int i; int has_preview = 0; for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i) { if (in[i]->data) { NodeImageMultiFileSocket *sockdata = sock->storage; ImageFormatData *format = (sockdata->use_node_format ? &nimf->format : &sockdata->format); char path[FILE_MAX]; char filename[FILE_MAX]; CompBuf *cbuf; ImBuf *ibuf; switch (format->planes) { case R_IMF_PLANES_BW: cbuf = typecheck_compbuf(in[i]->data, CB_VAL); break; case R_IMF_PLANES_RGB: cbuf = typecheck_compbuf(in[i]->data, CB_VEC3); break; case R_IMF_PLANES_RGBA: cbuf = typecheck_compbuf(in[i]->data, CB_RGBA); break; } ibuf = IMB_allocImBuf(cbuf->x, cbuf->y, format->planes, 0); /* XXX have to set this explicitly it seems */ switch (format->planes) { case R_IMF_PLANES_BW: ibuf->channels = 1; break; case R_IMF_PLANES_RGB: ibuf->channels = 3; break; case R_IMF_PLANES_RGBA: ibuf->channels = 4; break; } ibuf->rect_float = cbuf->rect; ibuf->dither = rd->dither_intensity; if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) ibuf->profile = IB_PROFILE_LINEAR_RGB; /* get full path */ BLI_join_dirfile(path, FILE_MAX, nimf->base_path, sockdata->path); BKE_makepicstring(filename, path, bmain->name, rd->cfra, format->imtype, (rd->scemode & R_EXTENSION), TRUE); if (0 == BKE_imbuf_write(ibuf, filename, format)) printf("Cannot save Node File Output to %s\n", filename); else printf("Saved: %s\n", filename); IMB_freeImBuf(ibuf); /* simply pick the first valid input for preview */ if (!has_preview) { generate_preview(rd, node, cbuf); has_preview = 1; } if (in[i]->data != cbuf) free_compbuf(cbuf); } } }