예제 #1
0
/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
void IMB_partial_rect_from_float(ImBuf *ibuf, float *buffer, int x, int y, int w, int h, bool is_data)
{
	const float *rect_float;
	uchar *rect_byte;
	int profile_from = IB_PROFILE_LINEAR_RGB;

	/* verify we have a float buffer */
	if (ibuf->rect_float == NULL || buffer == NULL)
		return;

	/* create byte rect if it didn't exist yet */
	if (ibuf->rect == NULL)
		imb_addrectImBuf(ibuf);

	/* do conversion */
	rect_float = ibuf->rect_float + (x + ((size_t)y) * ibuf->x) * ibuf->channels;
	rect_byte = (uchar *)ibuf->rect + (x + ((size_t)y) * ibuf->x) * 4;

	if (is_data) {
		/* exception for non-color data, just copy float */
		IMB_buffer_float_from_float(buffer, rect_float,
		                            ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, 0,
		                            w, h, w, ibuf->x);

		/* and do color space conversion to byte */
		IMB_buffer_byte_from_float(rect_byte, rect_float,
		                           4, ibuf->dither, IB_PROFILE_SRGB, profile_from, true,
		                           w, h, ibuf->x, w);
	}
	else {
		IMB_buffer_float_from_float(buffer, rect_float,
		                            ibuf->channels, IB_PROFILE_SRGB, profile_from, true,
		                            w, h, w, ibuf->x);

		IMB_buffer_float_unpremultiply(buffer, w, h);
		/* XXX: need to convert to image buffer's rect space */
		IMB_buffer_byte_from_float(rect_byte, buffer,
		                           4, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, 0,
		                           w, h, ibuf->x, w);
	}

	/* ensure user flag is reset */
	ibuf->userflags &= ~IB_RECT_INVALID;
}
예제 #2
0
파일: divers.c 프로젝트: dfelinto/blender
static void imb_buffer_float_from_float_thread_do(void *data_v,
                                                  int start_scanline,
                                                  int num_scanlines)
{
  FloatToFloatThreadData *data = (FloatToFloatThreadData *)data_v;
  size_t offset_from = ((size_t)start_scanline) * data->stride_from * data->channels_from;
  size_t offset_to = ((size_t)start_scanline) * data->stride_to * data->channels_from;
  IMB_buffer_float_from_float(data->rect_to + offset_to,
                              data->rect_from + offset_from,
                              data->channels_from,
                              data->profile_to,
                              data->profile_from,
                              data->predivide,
                              data->width,
                              num_scanlines,
                              data->stride_to,
                              data->stride_from);
}
예제 #3
0
파일: divers.c 프로젝트: dfelinto/blender
void IMB_buffer_float_from_float_threaded(float *rect_to,
                                          const float *rect_from,
                                          int channels_from,
                                          int profile_to,
                                          int profile_from,
                                          bool predivide,
                                          int width,
                                          int height,
                                          int stride_to,
                                          int stride_from)
{
  if (((size_t)width) * height < 64 * 64) {
    IMB_buffer_float_from_float(rect_to,
                                rect_from,
                                channels_from,
                                profile_to,
                                profile_from,
                                predivide,
                                width,
                                height,
                                stride_to,
                                stride_from);
  }
  else {
    FloatToFloatThreadData data;
    data.rect_to = rect_to;
    data.rect_from = rect_from;
    data.channels_from = channels_from;
    data.profile_to = profile_to;
    data.profile_from = profile_from;
    data.predivide = predivide;
    data.width = width;
    data.stride_to = stride_to;
    data.stride_from = stride_from;
    IMB_processor_apply_threaded_scanlines(height, imb_buffer_float_from_float_thread_do, &data);
  }
}
예제 #4
0
static void imb_stereo3d_squeeze_rectf(float *rectf, Stereo3dFormat *s3d, const size_t x, const size_t y, const size_t channels)
{
	ImBuf *ibuf;
	size_t width, height;

	if (ELEM(s3d->display_mode, S3D_DISPLAY_SIDEBYSIDE, S3D_DISPLAY_TOPBOTTOM) == false)
		return;

	if ((s3d->flag & S3D_SQUEEZED_FRAME) == 0)
		return;

	/* creates temporary imbuf to store the rectf */
	IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height);
	ibuf = IMB_allocImBuf(width, height, channels, IB_rectfloat);

	IMB_buffer_float_from_float(
	        ibuf->rect_float, rectf, channels,
	        IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
	        width, height, width, width);

	IMB_scaleImBuf_threaded(ibuf, x, y);
	memcpy(rectf, ibuf->rect_float, x * y * sizeof(float[4]));
	IMB_freeImBuf(ibuf);
}
예제 #5
0
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;
}
예제 #6
0
static bool write_internal_bake_pixels(
        Image *image, BakePixel pixel_array[], float *buffer,
        const int width, const int height, const int margin,
        const bool is_clear, const bool is_noncolor)
{
	ImBuf *ibuf;
	void *lock;
	bool is_float;
	char *mask_buffer = NULL;
	const size_t num_pixels = (size_t)width * (size_t)height;

	ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);

	if (!ibuf)
		return false;

	if (margin > 0 || !is_clear) {
		mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
		RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
	}

	is_float = (ibuf->flags & IB_rectfloat);

	/* colormanagement conversions */
	if (!is_noncolor) {
		const char *from_colorspace;
		const char *to_colorspace;

		from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);

		if (is_float)
			to_colorspace = IMB_colormanagement_get_float_colorspace(ibuf);
		else
			to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);

		if (from_colorspace != to_colorspace)
			IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
	}

	/* populates the ImBuf */
	if (is_clear) {
		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 {
			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);
		}
	}
	else {
		if (is_float) {
			IMB_buffer_float_from_float_mask(
			        ibuf->rect_float, buffer, ibuf->channels,
			        ibuf->x, ibuf->y, ibuf->x, ibuf->x, mask_buffer);
		}
		else {
			IMB_buffer_byte_from_float_mask(
			        (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
			        false, ibuf->x, ibuf->y, ibuf->x, ibuf->x, mask_buffer);
		}
	}

	/* margins */
	if (margin > 0)
		RE_bake_margin(ibuf, mask_buffer, margin);

	ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_BITMAPDIRTY;

	if (ibuf->rect_float)
		ibuf->userflags |= IB_RECT_INVALID;

	/* force mipmap recalc */
	if (ibuf->mipmap[0]) {
		ibuf->userflags |= IB_MIPMAP_INVALID;
		imb_freemipmapImBuf(ibuf);
	}

	BKE_image_release_ibuf(image, ibuf, NULL);

	if (mask_buffer)
		MEM_freeN(mask_buffer);

	return true;
}