void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap) { int nx= power_of_2_min_i(x); int ny= power_of_2_min_i(y); ImBuf *ibuf = IMB_allocFromBuffer(pix, NULL, x, y); IMB_scaleImBuf(ibuf, nx, ny); glBindTexture(GL_TEXTURE_2D, mTexture ); if ( mipmap ) { int i; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); IMB_makemipmap(ibuf, true); for (i = 0; i < ibuf->miptot; i++) { ImBuf *mip = IMB_getmipmap(ibuf, i); glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, mip->x, mip->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip->rect); } } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nx, ny, 0, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect ); } if (GLEW_EXT_texture_filter_anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, GPU_get_anisotropic()); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); IMB_freeImBuf(ibuf); }
static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted) { char name[FILE_MAX]; int quality, rectx, recty; int size = rendersize_to_number(proxy_render_size); ImBuf *scaleibuf; get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name); rectx = ibuf->x * size / 100.0f; recty = ibuf->y * size / 100.0f; scaleibuf = IMB_dupImBuf(ibuf); IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty); quality = clip->proxy.quality; scaleibuf->ftype = JPG | quality; /* unsupported feature only confuses other s/w */ if (scaleibuf->planes == 32) scaleibuf->planes = 24; BLI_lock_thread(LOCK_MOVIECLIP); BLI_make_existing_file(name); if (IMB_saveiff(scaleibuf, name, IB_rect) == 0) perror(name); BLI_unlock_thread(LOCK_MOVIECLIP); IMB_freeImBuf(scaleibuf); }
/* node->custom1 stores if input values are absolute or relative scale */ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { if(out[0]->hasoutput==0) return; if(in[0]->data) { RenderData *rd= data; CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); ImBuf *ibuf; int newx, newy; if(node->custom1==CMP_SCALE_RELATIVE) { newx= MAX2((int)(in[1]->vec[0]*cbuf->x), 1); newy= MAX2((int)(in[2]->vec[0]*cbuf->y), 1); } else if(node->custom1==CMP_SCALE_SCENEPERCENT) { newx = cbuf->x * (rd->size / 100.0f); newy = cbuf->y * (rd->size / 100.0f); } else { /* CMP_SCALE_ABSOLUTE */ newx= MAX2((int)in[1]->vec[0], 1); newy= MAX2((int)in[2]->vec[0], 1); } newx= MIN2(newx, CMP_SCALE_MAX); newy= MIN2(newy, CMP_SCALE_MAX); ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0, 0); if(ibuf) { ibuf->rect_float= cbuf->rect; IMB_scaleImBuf(ibuf, newx, newy); if(ibuf->rect_float == cbuf->rect) { /* no scaling happened. */ stackbuf= pass_on_compbuf(in[0]->data); } else { stackbuf= alloc_compbuf(newx, newy, CB_RGBA, 0); stackbuf->rect= ibuf->rect_float; stackbuf->malloc= 1; } ibuf->rect_float= NULL; ibuf->mall &= ~IB_rectfloat; IMB_freeImBuf(ibuf); /* also do the translation vector */ stackbuf->xof = (int)(((float)newx/(float)cbuf->x) * (float)cbuf->xof); stackbuf->yof = (int)(((float)newy/(float)cbuf->y) * (float)cbuf->yof); } else { stackbuf= dupalloc_compbuf(cbuf); printf("Scaling to %dx%d failed\n", newx, newy); } out[0]->data= stackbuf; if(cbuf!=in[0]->data) free_compbuf(cbuf); } };
static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect), int rw, int rh, unsigned int *rect, float alpha, const float rgb[3], const bool is_preview) { ImBuf *ima = NULL; /* sanity check */ if (w <= 0 || h <= 0 || w > 2000 || h > 2000) { printf("%s: icons are %i x %i pixels?\n", __func__, w, h); BLI_assert(!"invalid icon size"); return; } /* modulate color */ if (alpha != 1.0f) glPixelTransferf(GL_ALPHA_SCALE, alpha); if (rgb) { glPixelTransferf(GL_RED_SCALE, rgb[0]); glPixelTransferf(GL_GREEN_SCALE, rgb[1]); glPixelTransferf(GL_BLUE_SCALE, rgb[2]); } /* rect contains image in 'rendersize', we only scale if needed */ if (rw != w && rh != h) { /* first allocate imbuf for scaling and copy preview into it */ ima = IMB_allocImBuf(rw, rh, 32, IB_rect); memcpy(ima->rect, rect, rw * rh * sizeof(unsigned int)); IMB_scaleImBuf(ima, w, h); /* scale it */ rect = ima->rect; } /* draw */ if (is_preview) { glaDrawPixelsSafe(x, y, w, h, w, GL_RGBA, GL_UNSIGNED_BYTE, rect); } else { glRasterPos2f(x, y); glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect); } if (ima) IMB_freeImBuf(ima); /* restore color */ if (alpha != 0.0f) glPixelTransferf(GL_ALPHA_SCALE, 1.0f); if (rgb) { glPixelTransferf(GL_RED_SCALE, 1.0f); glPixelTransferf(GL_GREEN_SCALE, 1.0f); glPixelTransferf(GL_BLUE_SCALE, 1.0f); } }
static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *distortion, ImBuf *ibuf) { ImBuf *undistibuf; if (distortion) undistibuf = BKE_tracking_distortion_exec(distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1); else undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y); return undistibuf; }
/** Handle deferred (lazy) loading/generation of preview image, if needed. * For now, only used with file thumbnails. */ void BKE_previewimg_ensure(PreviewImage *prv, const int size) { if (prv->use_deferred) { const bool do_icon = ((size == ICON_SIZE_ICON) && !prv->rect[ICON_SIZE_ICON]); const bool do_preview = ((size == ICON_SIZE_PREVIEW) && !prv->rect[ICON_SIZE_PREVIEW]); if (do_icon || do_preview) { ImBuf *thumb; char *prv_deferred_data = PRV_DEFERRED_DATA(prv); int source = prv_deferred_data[0]; char *path = &prv_deferred_data[1]; int icon_w, icon_h; thumb = IMB_thumb_manage(path, THB_LARGE, source); if (thumb) { /* PreviewImage assumes premultiplied alhpa... */ IMB_premultiply_alpha(thumb); if (do_preview) { prv->w[ICON_SIZE_PREVIEW] = thumb->x; prv->h[ICON_SIZE_PREVIEW] = thumb->y; prv->rect[ICON_SIZE_PREVIEW] = MEM_dupallocN(thumb->rect); prv->flag[ICON_SIZE_PREVIEW] &= ~(PRV_CHANGED | PRV_USER_EDITED); } if (do_icon) { if (thumb->x > thumb->y) { icon_w = ICON_RENDER_DEFAULT_HEIGHT; icon_h = (thumb->y * icon_w) / thumb->x + 1; } else if (thumb->x < thumb->y) { icon_h = ICON_RENDER_DEFAULT_HEIGHT; icon_w = (thumb->x * icon_h) / thumb->y + 1; } else { icon_w = icon_h = ICON_RENDER_DEFAULT_HEIGHT; } IMB_scaleImBuf(thumb, icon_w, icon_h); prv->w[ICON_SIZE_ICON] = icon_w; prv->h[ICON_SIZE_ICON] = icon_h; prv->rect[ICON_SIZE_ICON] = MEM_dupallocN(thumb->rect); prv->flag[ICON_SIZE_ICON] &= ~(PRV_CHANGED | PRV_USER_EDITED); } IMB_freeImBuf(thumb); } } } }
static void icon_verify_datatoc(IconImage *iimg) { /* if it has own rect, things are all OK */ if (iimg->rect) return; if (iimg->datatoc_rect) { ImBuf *bbuf = IMB_ibImageFromMemory(iimg->datatoc_rect, iimg->datatoc_size, IB_rect, NULL, "<matcap icon>"); /* w and h were set on initialize */ if (bbuf->x != iimg->h && bbuf->y != iimg->w) IMB_scaleImBuf(bbuf, iimg->w, iimg->h); iimg->rect = bbuf->rect; bbuf->rect = NULL; IMB_freeImBuf(bbuf); } }
static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, bool undistorted, bool threaded) { char name[FILE_MAX]; int quality, rectx, recty; int size = rendersize_to_number(proxy_render_size); ImBuf *scaleibuf; get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name); rectx = ibuf->x * size / 100.0f; recty = ibuf->y * size / 100.0f; scaleibuf = IMB_dupImBuf(ibuf); if (threaded) IMB_scaleImBuf_threaded(scaleibuf, (short)rectx, (short)recty); else IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty); quality = clip->proxy.quality; scaleibuf->ftype = JPG | quality; /* unsupported feature only confuses other s/w */ if (scaleibuf->planes == 32) scaleibuf->planes = 24; /* TODO: currently the most weak part of multithreaded proxies, * could be solved in a way that thread only prepares memory * buffer and write to disk happens separately */ BLI_lock_thread(LOCK_MOVIECLIP); BLI_make_existing_file(name); if (IMB_saveiff(scaleibuf, name, IB_rect) == 0) perror(name); BLI_unlock_thread(LOCK_MOVIECLIP); IMB_freeImBuf(scaleibuf); }
static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *distortion, ImBuf *ibuf) { ImBuf *undistibuf; /* XXX: because of #27997 do not use float buffers to undistort, * otherwise, undistorted proxy can be darker than it should */ imb_freerectfloatImBuf(ibuf); if (distortion) undistibuf = BKE_tracking_distortion_exec(distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1); else undistibuf = BKE_tracking_undistort(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); if (undistibuf->userflags & IB_RECT_INVALID) { ibuf->userflags &= ~IB_RECT_INVALID; IMB_rect_from_float(undistibuf); } IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y); return undistibuf; }
/* screen can be NULL */ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, BlendThumbnail **thumb_pt) { /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; BlendThumbnail *thumb; char err_out[256] = "unknown"; /* screen if no camera found */ ScrArea *sa = NULL; ARegion *ar = NULL; View3D *v3d = NULL; /* In case we are given a valid thumbnail data, just generate image from it. */ if (*thumb_pt) { thumb = *thumb_pt; return BKE_main_thumbnail_to_imbuf(NULL, thumb); } /* scene can be NULL if running a script at startup and calling the save operator */ if (G.background || scene == NULL) return NULL; if ((scene->camera == NULL) && (screen != NULL)) { sa = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0); ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (ar) { v3d = sa->spacedata.first; } } if (scene->camera == NULL && v3d == NULL) { return NULL; } /* gets scaled to BLEN_THUMB_SIZE */ if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple( scene, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, OB_SOLID, false, false, false, R_ALPHAPREMUL, 0, false, NULL, NULL, NULL, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf( scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, false, R_ALPHAPREMUL, 0, false, NULL, NULL, NULL, err_out); } if (ibuf) { float aspect = (scene->r.xsch * scene->r.xasp) / (scene->r.ysch * scene->r.yasp); /* dirty oversampling */ IMB_scaleImBuf(ibuf, BLEN_THUMB_SIZE, BLEN_THUMB_SIZE); /* add pretty overlay */ IMB_thumb_overlay_blend(ibuf->rect, ibuf->x, ibuf->y, aspect); thumb = BKE_main_thumbnail_from_imbuf(NULL, ibuf); } else { /* '*thumb_pt' needs to stay NULL to prevent a bad thumbnail from being handled */ fprintf(stderr, "blend_file_thumb failed to create thumbnail: %s\n", err_out); thumb = NULL; } /* must be freed by caller */ *thumb_pt = thumb; return ibuf; }
void Canvas::loadMap(const char *iFileName, const char *iMapName, unsigned int iNbLevels, float iSigma) { // check whether this map was already loaded: if (!_maps.empty()) { mapsMap::iterator m = _maps.find(iMapName); if (m != _maps.end()) { // lazy check for size changes ImagePyramid *pyramid = (*m).second; if ((pyramid->width() != width()) || (pyramid->height() != height())) { delete pyramid; } else { return; } } } string filePath; if (_MapsPath) { filePath = _MapsPath; filePath += iFileName; } else { filePath = iFileName; } #if 0 //soc QImage *qimg; QImage newMap(filePath.c_str()); if (newMap.isNull()) { cerr << "Could not load image file " << filePath << endl; return; } qimg = &newMap; #endif /* OCIO_TODO: support different input color space */ ImBuf *qimg = IMB_loadiffname(filePath.c_str(), 0, NULL); if (qimg == 0) { cerr << "Could not load image file " << filePath << endl; return; } #if 0 // soc // resize QImage scaledImg; if ((newMap.width() != width()) || (newMap.height() != height())) { scaledImg = newMap.scaled(width(), height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); qimg = &scaledImg; } #endif ImBuf *scaledImg; if ((qimg->x != width()) || (qimg->y != height())) { scaledImg = IMB_dupImBuf(qimg); IMB_scaleImBuf(scaledImg, width(), height()); } // deal with color image #if 0 if (newMap->depth() != 8) { int w = newMap->width(); int h = newMap->height(); QImage *tmp = new QImage(w, h, 8); for (unsigned int y = 0; y < h; ++y) { for (unsigned int x = 0; x < w; ++x) { int c = qGray(newMap->pixel(x, y)); tmp->setPixel(x, y, c); } } delete newMap; newMap = tmp; } #endif int x, y; int w = qimg->x; int h = qimg->y; int rowbytes = w * 4; GrayImage tmp(w, h); char *pix; for (y = 0; y < h; ++y) { for (x = 0; x < w; ++x) { pix = (char *)qimg->rect + y * rowbytes + x * 4; float c = (pix[0] * 11 + pix[1] * 16 + pix[2] * 5) / 32; tmp.setPixel(x, y, c); } } #if 0 GrayImage blur(w, h); GaussianFilter gf(4.0f); //int bound = gf.getBound(); for (y = 0; y < h; ++y) { for (x = 0; x < w; ++x) { int c = gf.getSmoothedPixel<GrayImage>(&tmp, x, y); blur.setPixel(x, y, c); } } #endif GaussianPyramid *pyramid = new GaussianPyramid(tmp, iNbLevels, iSigma); int ow = pyramid->width(0); int oh = pyramid->height(0); string base(iMapName); //soc for (int i = 0; i < pyramid->getNumberOfLevels(); ++i) { // save each image: #if 0 w = pyramid.width(i); h = pyramid.height(i); #endif //soc QImage qtmp(ow, oh, QImage::Format_RGB32); ImBuf *qtmp = IMB_allocImBuf(ow, oh, 32, IB_rect); //int k = (1 << i); for (y = 0; y < oh; ++y) { for (x = 0; x < ow; ++x) { int c = pyramid->pixel(x, y, i); // 255 * pyramid->pixel(x, y, i); //soc qtmp.setPixel(x, y, qRgb(c, c, c)); pix = (char *)qtmp->rect + y * rowbytes + x * 4; pix[0] = pix[1] = pix[2] = c; } } //soc qtmp.save(base + QString::number(i) + ".bmp", "BMP"); stringstream filename; filename << base; filename << i << ".bmp"; qtmp->ftype = BMP; IMB_saveiff(qtmp, const_cast<char *>(filename.str().c_str()), 0); } #if 0 QImage *qtmp = new QImage(w, h, 32); for (y = 0; y < h; ++y) { for (x = 0; x < w; ++x) { int c = (int)blur.pixel(x, y); qtmp->setPixel(x, y, qRgb(c, c, c)); } } delete newMap; newMap = qtmp; #endif _maps[iMapName] = pyramid; //newMap->save("toto.bmp", "BMP"); }
static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect), int rw, int rh, unsigned int *rect, float alpha, const float rgb[3], const bool is_preview) { ImBuf *ima = NULL; int draw_w = w; int draw_h = h; int draw_x = x; int draw_y = y; /* sanity check */ if (w <= 0 || h <= 0 || w > 2000 || h > 2000) { printf("%s: icons are %i x %i pixels?\n", __func__, w, h); BLI_assert(!"invalid icon size"); return; } /* modulate color */ if (alpha != 1.0f) glPixelTransferf(GL_ALPHA_SCALE, alpha); if (rgb) { glPixelTransferf(GL_RED_SCALE, rgb[0]); glPixelTransferf(GL_GREEN_SCALE, rgb[1]); glPixelTransferf(GL_BLUE_SCALE, rgb[2]); } /* rect contains image in 'rendersize', we only scale if needed */ if (rw != w || rh != h) { /* preserve aspect ratio and center */ if (rw > rh) { draw_w = w; draw_h = (int)(((float)rh / (float)rw) * (float)w); draw_y += (h - draw_h) / 2; } else if (rw < rh) { draw_w = (int)(((float)rw / (float)rh) * (float)h); draw_h = h; draw_x += (w - draw_w) / 2; } /* if the image is squared, the draw_ initialization values are good */ /* first allocate imbuf for scaling and copy preview into it */ ima = IMB_allocImBuf(rw, rh, 32, IB_rect); memcpy(ima->rect, rect, rw * rh * sizeof(unsigned int)); IMB_scaleImBuf(ima, draw_w, draw_h); /* scale it */ rect = ima->rect; } /* draw */ if (is_preview) { glaDrawPixelsSafe(draw_x, draw_y, draw_w, draw_h, draw_w, GL_RGBA, GL_UNSIGNED_BYTE, rect); } else { glRasterPos2f(draw_x, draw_y); glDrawPixels(draw_w, draw_h, GL_RGBA, GL_UNSIGNED_BYTE, rect); } if (ima) IMB_freeImBuf(ima); /* restore color */ if (alpha != 0.0f) glPixelTransferf(GL_ALPHA_SCALE, 1.0f); if (rgb) { glPixelTransferf(GL_RED_SCALE, 1.0f); glPixelTransferf(GL_GREEN_SCALE, 1.0f); glPixelTransferf(GL_BLUE_SCALE, 1.0f); } }
LIBEXPORT struct ImBuf *scaleImBuf(struct ImBuf *ib, short nx, short ny) { return IMB_scaleImBuf(ib, nx, ny); }
static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, int clip_index, int frame, libmv_InputMode input_mode, int downscale, const libmv_Region *region, const libmv_FrameTransform *transform) { ImBuf *ibuf, *orig_ibuf, *final_ibuf; int64_t transform_key = 0; if (transform != NULL) { transform_key = libmv_frameAccessorgetTransformKey(transform); } /* First try to get fully processed image from the cache. */ ibuf = accesscache_get(accessor, clip_index, frame, input_mode, downscale, transform_key); if (ibuf != NULL) { return ibuf; } /* And now we do postprocessing of the original frame. */ orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame); if (orig_ibuf == NULL) { return NULL; } if (region != NULL) { int width = region->max[0] - region->min[0], height = region->max[1] - region->min[1]; /* If the requested region goes outside of the actual frame we still * return the requested region size, but only fill it's partially with * the data we can. */ int clamped_origin_x = max_ii((int)region->min[0], 0), clamped_origin_y = max_ii((int)region->min[1], 0); int dst_offset_x = clamped_origin_x - (int)region->min[0], dst_offset_y = clamped_origin_y - (int)region->min[1]; int clamped_width = width - dst_offset_x, clamped_height = height - dst_offset_y; clamped_width = min_ii(clamped_width, orig_ibuf->x - clamped_origin_x); clamped_height = min_ii(clamped_height, orig_ibuf->y - clamped_origin_y); final_ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat); if (orig_ibuf->rect_float != NULL) { IMB_rectcpy(final_ibuf, orig_ibuf, dst_offset_x, dst_offset_y, clamped_origin_x, clamped_origin_y, clamped_width, clamped_height); } else { int y; /* TODO(sergey): We don't do any color space or alpha conversion * here. Probably Libmv is better to work in the linear space, * but keep sRGB space here for compatibility for now. */ for (y = 0; y < clamped_height; ++y) { int x; for (x = 0; x < clamped_width; ++x) { int src_x = x + clamped_origin_x, src_y = y + clamped_origin_y; int dst_x = x + dst_offset_x, dst_y = y + dst_offset_y; int dst_index = (dst_y * width + dst_x) * 4, src_index = (src_y * orig_ibuf->x + src_x) * 4; rgba_uchar_to_float(final_ibuf->rect_float + dst_index, (unsigned char *)orig_ibuf->rect + src_index); } } } } else { /* Libmv only works with float images, * * This would likely make it so loads of float buffers are being stored * in the cache which is nice on the one hand (faster re-use of the * frames) but on the other hand it bumps the memory usage up. */ BLI_lock_thread(LOCK_MOVIECLIP); IMB_float_from_rect(orig_ibuf); BLI_unlock_thread(LOCK_MOVIECLIP); final_ibuf = orig_ibuf; } if (downscale > 0) { if (final_ibuf == orig_ibuf) { final_ibuf = IMB_dupImBuf(orig_ibuf); } IMB_scaleImBuf(final_ibuf, ibuf->x / (1 << downscale), ibuf->y / (1 << downscale)); } if (transform != NULL) { libmv_FloatImage input_image, output_image; ibuf_to_float_image(final_ibuf, &input_image); libmv_frameAccessorgetTransformRun(transform, &input_image, &output_image); if (final_ibuf != orig_ibuf) { IMB_freeImBuf(final_ibuf); } final_ibuf = float_image_to_ibuf(&output_image); libmv_floatImageDestroy(&output_image); } if (input_mode == LIBMV_IMAGE_MODE_RGBA) { BLI_assert(ibuf->channels == 3 || ibuf->channels == 4); /* pass */ } else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ { if (final_ibuf->channels != 1) { ImBuf *grayscale_ibuf = make_grayscale_ibuf_copy(final_ibuf); if (final_ibuf != orig_ibuf) { /* We dereference original frame later. */ IMB_freeImBuf(final_ibuf); } final_ibuf = grayscale_ibuf; } } /* it's possible processing still didn't happen at this point, * but we really need a copy of the buffer to be transformed * and to be put to the cache. */ if (final_ibuf == orig_ibuf) { final_ibuf = IMB_dupImBuf(orig_ibuf); } IMB_freeImBuf(orig_ibuf); /* We put postprocessed frame to the cache always for now, * not the smartest thing in the world, but who cares at this point. */ /* TODO(sergey): Disable cache for now, because we don't store region * in the cache key and can't check whether cached version is usable for * us or not. * * Need to think better about what to cache and when. */ if (false) { accesscache_put(accessor, clip_index, frame, input_mode, downscale, transform_key, final_ibuf); } return final_ibuf; }
/* screen can be NULL */ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt) { /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; int *thumb; char err_out[256] = "unknown"; /* screen if no camera found */ ScrArea *sa = NULL; ARegion *ar = NULL; View3D *v3d = NULL; *thumb_pt = NULL; /* scene can be NULL if running a script at startup and calling the save operator */ if (G.background || scene == NULL) return NULL; if ((scene->camera == NULL) && (screen != NULL)) { sa = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0); ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (ar) { v3d = sa->spacedata.first; } } if (scene->camera == NULL && v3d == NULL) { return NULL; } /* gets scaled to BLEN_THUMB_SIZE */ if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, OB_SOLID, FALSE, FALSE, R_ADDSKY, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, IB_rect, FALSE, R_ADDSKY, err_out); } if (ibuf) { float aspect = (scene->r.xsch * scene->r.xasp) / (scene->r.ysch * scene->r.yasp); /* dirty oversampling */ IMB_scaleImBuf(ibuf, BLEN_THUMB_SIZE, BLEN_THUMB_SIZE); /* add pretty overlay */ IMB_overlayblend_thumb(ibuf->rect, ibuf->x, ibuf->y, aspect); /* first write into thumb buffer */ thumb = MEM_mallocN(((2 + (BLEN_THUMB_SIZE * BLEN_THUMB_SIZE))) * sizeof(int), "write_file thumb"); thumb[0] = BLEN_THUMB_SIZE; thumb[1] = BLEN_THUMB_SIZE; memcpy(thumb + 2, ibuf->rect, BLEN_THUMB_SIZE * BLEN_THUMB_SIZE * sizeof(int)); } else { /* '*thumb_pt' needs to stay NULL to prevent a bad thumbnail from being handled */ fprintf(stderr, "blend_file_thumb failed to create thumbnail: %s\n", err_out); thumb = NULL; } /* must be freed by caller */ *thumb_pt = thumb; return ibuf; }
// refresh texture static PyObject *Texture_refresh(Texture *self, PyObject *args) { // get parameter - refresh source PyObject *param; double ts = -1.0; if (!PyArg_ParseTuple(args, "O|d:refresh", ¶m, &ts) || !PyBool_Check(param)) { // report error PyErr_SetString(PyExc_TypeError, "The value must be a bool"); return NULL; } // some trick here: we are in the business of loading a texture, // no use to do it if we are still in the same rendering frame. // We find this out by looking at the engine current clock time KX_KetsjiEngine* engine = KX_GetActiveEngine(); if (engine->GetClockTime() != self->m_lastClock) { self->m_lastClock = engine->GetClockTime(); // set source refresh bool refreshSource = (param == Py_True); // try to proces texture from source try { // if source is available if (self->m_source != NULL) { // check texture code if (!self->m_orgSaved) { self->m_orgSaved = true; // save original image code if (self->m_useMatTexture) self->m_orgTex = self->m_matTexture->swapTexture(self->m_actTex); else { // Swapping will work only if the GPU has already loaded the image. // If not, it will delete and overwrite our texture on next render. // To avoid that, we acquire the image buffer now. // WARNING: GPU has a ImageUser to pass, we don't. Using NULL // works on image file, not necessarily on other type of image. self->m_imgBuf = BKE_image_acquire_ibuf(self->m_imgTexture, NULL, NULL); self->m_orgTex = self->m_imgTexture->bindcode[TEXTARGET_TEXTURE_2D]; self->m_imgTexture->bindcode[TEXTARGET_TEXTURE_2D] = self->m_actTex; } } // get texture unsigned int * texture = self->m_source->m_image->getImage(self->m_actTex, ts); // if texture is available if (texture != NULL) { // get texture size short * orgSize = self->m_source->m_image->getSize(); // calc scaled sizes short size[2]; if (GLEW_ARB_texture_non_power_of_two) { size[0] = orgSize[0]; size[1] = orgSize[1]; } else { size[0] = ImageBase::calcSize(orgSize[0]); size[1] = ImageBase::calcSize(orgSize[1]); } // scale texture if needed if (size[0] != orgSize[0] || size[1] != orgSize[1]) { IMB_freeImBuf(self->m_scaledImBuf); self->m_scaledImBuf = IMB_allocFromBuffer(texture, NULL, orgSize[0], orgSize[1]); IMB_scaleImBuf(self->m_scaledImBuf, size[0], size[1]); // use scaled image instead original texture = self->m_scaledImBuf->rect; } // load texture for rendering loadTexture(self->m_actTex, texture, size, self->m_mipmap); } // refresh texture source, if required if (refreshSource) { self->m_source->m_image->refresh(); } } } CATCH_EXCP; }