예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
파일: CMP_scale.c 프로젝트: jinjoh/NOOR
/* 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);
	}
};
예제 #4
0
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);
	}
}
예제 #5
0
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;
}
예제 #6
0
파일: icons.c 프로젝트: khanhha/blender
/** 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);
			}
		}
	}
}
예제 #7
0
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);
	}
}
예제 #8
0
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);
}
예제 #9
0
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;
}
예제 #10
0
/* 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;
}
예제 #11
0
파일: Canvas.cpp 프로젝트: 244xiao/blender
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");
}
예제 #12
0
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);
	}
}
예제 #13
0
LIBEXPORT struct ImBuf *scaleImBuf(struct ImBuf *ib,
                                   short nx,
                                   short ny)
{
    return IMB_scaleImBuf(ib, nx, ny);
}
예제 #14
0
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;
}
예제 #15
0
/* 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;
}
예제 #16
0
// 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", &param, &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;
	}