2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2008-04-16 22:40:48 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2008-04-16 22:40:48 +00:00
|
|
|
* of the License, or (at your option) any later version.
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2002-10-12 11:37:38 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
*
|
|
|
|
* Contributor(s): none yet.
|
|
|
|
*
|
2008-04-16 22:40:48 +00:00
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
2012-04-30 14:24:11 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/** \file blender/imbuf/intern/imageprocess.c
|
|
|
|
* \ingroup imbuf
|
|
|
|
*
|
2002-10-12 11:37:38 +00:00
|
|
|
* This file was moved here from the src/ directory. It is meant to
|
|
|
|
* deal with endianness. It resided in a general blending lib. The
|
|
|
|
* other functions were only used during rendering. This single
|
|
|
|
* function remained. It should probably move to imbuf/intern/util.c,
|
2012-04-30 14:24:11 +00:00
|
|
|
* but we'll keep it here for the time being. (nzc)
|
|
|
|
*
|
2011-02-27 20:23:21 +00:00
|
|
|
*/
|
|
|
|
|
Merge image related changes from the render branch. This includes the image
tile cache code in imbuf, but it is not hooked up to the render engine.
Imbuf module: some small refactoring and removing a lot of unused or old code
(about 6.5k lines).
* Added a ImFileType struct with callbacks to make adding an file format type,
or making changes to the API easier.
* Move imbuf init/exit code into IMB_init()/IMB_exit() functions.
* Increased mipmap levels from 10 to 20, you run into this limit already with
a 2k image.
* Removed hamx, amiga, anim5 format support.
* Removed colormap saving, only simple colormap code now for reading tga.
* Removed gen_dynlibtiff.py, editing this is almost as much work as just
editing the code directly.
* Functions removed that were only used for sequencer plugin API:
IMB_anim_nextpic, IMB_clever_double, IMB_antialias, IMB_gamwarp,
IMB_scalefieldImBuf, IMB_scalefastfieldImBuf, IMB_onethird, IMB_halflace,
IMB_dit0, IMB_dit2, IMB_cspace
* Write metadata info into OpenEXR images. Can be viewed with the command
line utility 'exrheader'
For the image tile cache code, see this page:
http://wiki.blender.org/index.php/Dev:2.5/Source/Imaging/ImageTileCache
2010-05-07 15:18:04 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
2012-08-07 16:47:46 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2012-03-08 14:23:34 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2013-12-25 20:32:13 +06:00
|
|
|
#include "BLI_task.h"
|
2012-11-11 08:48:35 +00:00
|
|
|
#include "BLI_math.h"
|
2012-03-08 14:23:34 +00:00
|
|
|
|
Orange branch: OpenEXR finally in Blender!
Credits go to Gernot Ziegler, who originally coded EXR support, and to
Austin Benesh for bringing it further. Kent Mein provided a lot of code
for integrating float buffers in Blender imbuf and ImBuf API cleanup,
and provided Make and Scons and static linking.
At this moment; the EXR libraries are a *dependency*, so you cannot get
the Orange branch compiled without having OpenEXR installed. Get the
(precompiled or sources) stuff from www.openexr.com. Current default is
that the headers and lib resides in /user/local/
Several changes/additions/fixes were added:
- EXR code only supported 'half' format (16 bits per channel). I've added
float writing, but for reading it I need tomorrow. :)
- Quite some clumsy copying of data happened in EXR code.
- cleaned up the api calls already a bit, preparing for more advanced
support
- Zbuffers were saved 16 bits, now 32 bits
- automatic adding of .exr extensions went wrong
Imbuf:
- added proper imbuf->flags and imbuf->mall support for float buffers, it
was created for *each* imbuf. :)
- found bugs for float buffers in scaling and flipping. Code there will
need more checks still
- imbuf also needs to be verified to behave properly when no 32 bits
rect exists (for saving for example)
TODO:
- support internal float images for textures, backbuf, AO probes, and
display in Image window
Hope this commit won't screwup syncing with bf-blender... :/
2006-01-09 00:40:35 +00:00
|
|
|
#include "IMB_imbuf_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "IMB_imbuf.h"
|
2012-04-06 04:46:47 +00:00
|
|
|
#include <math.h>
|
2007-07-10 19:13:03 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* Only this one is used liberally here, and in imbuf */
|
Orange branch: OpenEXR finally in Blender!
Credits go to Gernot Ziegler, who originally coded EXR support, and to
Austin Benesh for bringing it further. Kent Mein provided a lot of code
for integrating float buffers in Blender imbuf and ImBuf API cleanup,
and provided Make and Scons and static linking.
At this moment; the EXR libraries are a *dependency*, so you cannot get
the Orange branch compiled without having OpenEXR installed. Get the
(precompiled or sources) stuff from www.openexr.com. Current default is
that the headers and lib resides in /user/local/
Several changes/additions/fixes were added:
- EXR code only supported 'half' format (16 bits per channel). I've added
float writing, but for reading it I need tomorrow. :)
- Quite some clumsy copying of data happened in EXR code.
- cleaned up the api calls already a bit, preparing for more advanced
support
- Zbuffers were saved 16 bits, now 32 bits
- automatic adding of .exr extensions went wrong
Imbuf:
- added proper imbuf->flags and imbuf->mall support for float buffers, it
was created for *each* imbuf. :)
- found bugs for float buffers in scaling and flipping. Code there will
need more checks still
- imbuf also needs to be verified to behave properly when no 32 bits
rect exists (for saving for example)
TODO:
- support internal float images for textures, backbuf, AO probes, and
display in Image window
Hope this commit won't screwup syncing with bf-blender... :/
2006-01-09 00:40:35 +00:00
|
|
|
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2015-05-29 13:38:20 +02:00
|
|
|
size_t size;
|
Orange branch: OpenEXR finally in Blender!
Credits go to Gernot Ziegler, who originally coded EXR support, and to
Austin Benesh for bringing it further. Kent Mein provided a lot of code
for integrating float buffers in Blender imbuf and ImBuf API cleanup,
and provided Make and Scons and static linking.
At this moment; the EXR libraries are a *dependency*, so you cannot get
the Orange branch compiled without having OpenEXR installed. Get the
(precompiled or sources) stuff from www.openexr.com. Current default is
that the headers and lib resides in /user/local/
Several changes/additions/fixes were added:
- EXR code only supported 'half' format (16 bits per channel). I've added
float writing, but for reading it I need tomorrow. :)
- Quite some clumsy copying of data happened in EXR code.
- cleaned up the api calls already a bit, preparing for more advanced
support
- Zbuffers were saved 16 bits, now 32 bits
- automatic adding of .exr extensions went wrong
Imbuf:
- added proper imbuf->flags and imbuf->mall support for float buffers, it
was created for *each* imbuf. :)
- found bugs for float buffers in scaling and flipping. Code there will
need more checks still
- imbuf also needs to be verified to behave properly when no 32 bits
rect exists (for saving for example)
TODO:
- support internal float images for textures, backbuf, AO probes, and
display in Image window
Hope this commit won't screwup syncing with bf-blender... :/
2006-01-09 00:40:35 +00:00
|
|
|
unsigned char rt, *cp = (unsigned char *)ibuf->rect;
|
|
|
|
float rtf, *cpf = ibuf->rect_float;
|
|
|
|
|
2008-01-20 18:55:56 +00:00
|
|
|
if (ibuf->rect) {
|
|
|
|
size = ibuf->x * ibuf->y;
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
while (size-- > 0) {
|
2012-05-13 22:05:51 +00:00
|
|
|
rt = cp[0];
|
|
|
|
cp[0] = cp[3];
|
|
|
|
cp[3] = rt;
|
|
|
|
rt = cp[1];
|
|
|
|
cp[1] = cp[2];
|
|
|
|
cp[2] = rt;
|
|
|
|
cp += 4;
|
2008-01-20 18:55:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ibuf->rect_float) {
|
|
|
|
size = ibuf->x * ibuf->y;
|
|
|
|
|
2012-03-24 07:52:14 +00:00
|
|
|
while (size-- > 0) {
|
2012-05-13 22:05:51 +00:00
|
|
|
rtf = cpf[0];
|
|
|
|
cpf[0] = cpf[3];
|
|
|
|
cpf[3] = rtf;
|
|
|
|
rtf = cpf[1];
|
|
|
|
cpf[1] = cpf[2];
|
|
|
|
cpf[2] = rtf;
|
|
|
|
cpf += 4;
|
Orange branch: OpenEXR finally in Blender!
Credits go to Gernot Ziegler, who originally coded EXR support, and to
Austin Benesh for bringing it further. Kent Mein provided a lot of code
for integrating float buffers in Blender imbuf and ImBuf API cleanup,
and provided Make and Scons and static linking.
At this moment; the EXR libraries are a *dependency*, so you cannot get
the Orange branch compiled without having OpenEXR installed. Get the
(precompiled or sources) stuff from www.openexr.com. Current default is
that the headers and lib resides in /user/local/
Several changes/additions/fixes were added:
- EXR code only supported 'half' format (16 bits per channel). I've added
float writing, but for reading it I need tomorrow. :)
- Quite some clumsy copying of data happened in EXR code.
- cleaned up the api calls already a bit, preparing for more advanced
support
- Zbuffers were saved 16 bits, now 32 bits
- automatic adding of .exr extensions went wrong
Imbuf:
- added proper imbuf->flags and imbuf->mall support for float buffers, it
was created for *each* imbuf. :)
- found bugs for float buffers in scaling and flipping. Code there will
need more checks still
- imbuf also needs to be verified to behave properly when no 32 bits
rect exists (for saving for example)
TODO:
- support internal float images for textures, backbuf, AO probes, and
display in Image window
Hope this commit won't screwup syncing with bf-blender... :/
2006-01-09 00:40:35 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
2008-11-20 00:34:24 +00:00
|
|
|
static void pixel_from_buffer(struct ImBuf *ibuf, unsigned char **outI, float **outF, int x, int y)
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
|
|
|
{
|
2015-05-29 13:38:20 +02:00
|
|
|
size_t offset = ((size_t)ibuf->x) * y * 4 + 4 * x;
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
|
|
|
if (ibuf->rect)
|
2012-05-13 22:05:51 +00:00
|
|
|
*outI = (unsigned char *)ibuf->rect + offset;
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
|
|
|
if (ibuf->rect_float)
|
2012-08-02 11:33:21 +00:00
|
|
|
*outF = ibuf->rect_float + offset;
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
}
|
Orange branch: OpenEXR finally in Blender!
Credits go to Gernot Ziegler, who originally coded EXR support, and to
Austin Benesh for bringing it further. Kent Mein provided a lot of code
for integrating float buffers in Blender imbuf and ImBuf API cleanup,
and provided Make and Scons and static linking.
At this moment; the EXR libraries are a *dependency*, so you cannot get
the Orange branch compiled without having OpenEXR installed. Get the
(precompiled or sources) stuff from www.openexr.com. Current default is
that the headers and lib resides in /user/local/
Several changes/additions/fixes were added:
- EXR code only supported 'half' format (16 bits per channel). I've added
float writing, but for reading it I need tomorrow. :)
- Quite some clumsy copying of data happened in EXR code.
- cleaned up the api calls already a bit, preparing for more advanced
support
- Zbuffers were saved 16 bits, now 32 bits
- automatic adding of .exr extensions went wrong
Imbuf:
- added proper imbuf->flags and imbuf->mall support for float buffers, it
was created for *each* imbuf. :)
- found bugs for float buffers in scaling and flipping. Code there will
need more checks still
- imbuf also needs to be verified to behave properly when no 32 bits
rect exists (for saving for example)
TODO:
- support internal float images for textures, backbuf, AO probes, and
display in Image window
Hope this commit won't screwup syncing with bf-blender... :/
2006-01-09 00:40:35 +00:00
|
|
|
|
2012-11-11 08:48:35 +00:00
|
|
|
/* BICUBIC Interpolation */
|
2008-11-19 02:07:23 +00:00
|
|
|
|
2012-10-01 06:18:45 +00:00
|
|
|
void bicubic_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
|
2007-07-10 19:13:03 +00:00
|
|
|
{
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
if (outF) {
|
2012-11-11 08:48:35 +00:00
|
|
|
BLI_bicubic_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
|
|
|
|
}
|
|
|
|
else {
|
2012-12-28 14:19:05 +00:00
|
|
|
BLI_bicubic_interpolation_char((unsigned char *) in->rect, outI, in->x, in->y, 4, u, v);
|
2007-07-10 19:13:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
|
|
|
void bicubic_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
|
|
|
|
{
|
|
|
|
unsigned char *outI = NULL;
|
|
|
|
float *outF = NULL;
|
|
|
|
|
2012-10-01 06:18:45 +00:00
|
|
|
if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) {
|
|
|
|
return;
|
|
|
|
}
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
2008-11-20 00:34:24 +00:00
|
|
|
pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
|
|
|
bicubic_interpolation_color(in, outI, outF, u, v);
|
|
|
|
}
|
|
|
|
|
2007-07-10 19:13:03 +00:00
|
|
|
/* BILINEAR INTERPOLATION */
|
2012-10-01 06:18:45 +00:00
|
|
|
void bilinear_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
|
2007-07-10 19:13:03 +00:00
|
|
|
{
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
if (outF) {
|
2012-11-11 08:48:35 +00:00
|
|
|
BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v);
|
2007-07-10 19:13:03 +00:00
|
|
|
}
|
2012-11-11 08:48:35 +00:00
|
|
|
else {
|
2012-12-28 14:19:05 +00:00
|
|
|
BLI_bilinear_interpolation_char((unsigned char *) in->rect, outI, in->x, in->y, 4, u, v);
|
2009-05-28 06:13:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* function assumes out to be zero'ed, only does RGBA */
|
|
|
|
/* BILINEAR INTERPOLATION */
|
|
|
|
|
|
|
|
/* Note about wrapping, the u/v still needs to be within the image bounds,
|
|
|
|
* just the interpolation is wrapped.
|
2011-05-28 13:11:24 +00:00
|
|
|
* This the same as bilinear_interpolation_color except it wraps rather than using empty and emptyI */
|
2012-10-01 06:18:45 +00:00
|
|
|
void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
|
2009-05-28 06:13:56 +00:00
|
|
|
{
|
|
|
|
float *row1, *row2, *row3, *row4, a, b;
|
|
|
|
unsigned char *row1I, *row2I, *row3I, *row4I;
|
|
|
|
float a_b, ma_b, a_mb, ma_mb;
|
|
|
|
int y1, y2, x1, x2;
|
|
|
|
|
|
|
|
|
2010-07-17 18:08:14 +00:00
|
|
|
/* ImBuf in must have a valid rect or rect_float, assume this is already checked */
|
2009-05-28 06:13:56 +00:00
|
|
|
|
2012-05-13 22:05:51 +00:00
|
|
|
x1 = (int)floor(u);
|
|
|
|
x2 = (int)ceil(u);
|
|
|
|
y1 = (int)floor(v);
|
|
|
|
y2 = (int)ceil(v);
|
2009-05-28 06:13:56 +00:00
|
|
|
|
2012-07-07 22:51:57 +00:00
|
|
|
/* sample area entirely outside image? */
|
2012-10-01 06:18:45 +00:00
|
|
|
if (x2 < 0 || x1 > in->x - 1 || y2 < 0 || y1 > in->y - 1) {
|
|
|
|
return;
|
|
|
|
}
|
2012-07-07 22:51:57 +00:00
|
|
|
|
2009-05-28 06:13:56 +00:00
|
|
|
/* wrap interpolation pixels - main difference from bilinear_interpolation_color */
|
2012-05-13 22:05:51 +00:00
|
|
|
if (x1 < 0) x1 = in->x + x1;
|
|
|
|
if (y1 < 0) y1 = in->y + y1;
|
2012-07-07 22:51:57 +00:00
|
|
|
|
2012-05-13 22:05:51 +00:00
|
|
|
if (x2 >= in->x) x2 = x2 - in->x;
|
|
|
|
if (y2 >= in->y) y2 = y2 - in->y;
|
2009-05-28 06:13:56 +00:00
|
|
|
|
2014-10-17 14:11:13 +02:00
|
|
|
a = u - floorf(u);
|
|
|
|
b = v - floorf(v);
|
|
|
|
a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b);
|
|
|
|
|
2009-05-28 06:13:56 +00:00
|
|
|
if (outF) {
|
2012-07-07 22:51:57 +00:00
|
|
|
/* sample including outside of edges of image */
|
2015-05-29 13:38:20 +02:00
|
|
|
row1 = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1;
|
|
|
|
row2 = in->rect_float + ((size_t)in->x) * y2 * 4 + 4 * x1;
|
|
|
|
row3 = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x2;
|
|
|
|
row4 = in->rect_float + ((size_t)in->x) * y2 * 4 + 4 * x2;
|
2012-05-13 22:05:51 +00:00
|
|
|
|
|
|
|
outF[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
|
|
|
|
outF[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
|
|
|
|
outF[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
|
|
|
|
outF[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3];
|
2014-10-17 14:11:13 +02:00
|
|
|
|
|
|
|
/* clamp here or else we can easily get off-range */
|
|
|
|
CLAMP(outF[0], 0.0f, 1.0f);
|
|
|
|
CLAMP(outF[1], 0.0f, 1.0f);
|
|
|
|
CLAMP(outF[2], 0.0f, 1.0f);
|
|
|
|
CLAMP(outF[3], 0.0f, 1.0f);
|
2009-05-28 06:13:56 +00:00
|
|
|
}
|
|
|
|
if (outI) {
|
2012-07-07 22:51:57 +00:00
|
|
|
/* sample including outside of edges of image */
|
2015-05-29 13:38:20 +02:00
|
|
|
row1I = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1;
|
|
|
|
row2I = (unsigned char *)in->rect + ((size_t)in->x) * y2 * 4 + 4 * x1;
|
|
|
|
row3I = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x2;
|
|
|
|
row4I = (unsigned char *)in->rect + ((size_t)in->x) * y2 * 4 + 4 * x2;
|
2009-05-28 06:13:56 +00:00
|
|
|
|
|
|
|
/* need to add 0.5 to avoid rounding down (causes darken with the smear brush)
|
|
|
|
* tested with white images and this should not wrap back to zero */
|
2012-05-13 22:05:51 +00:00
|
|
|
outI[0] = (ma_mb * row1I[0] + a_mb * row3I[0] + ma_b * row2I[0] + a_b * row4I[0]) + 0.5f;
|
|
|
|
outI[1] = (ma_mb * row1I[1] + a_mb * row3I[1] + ma_b * row2I[1] + a_b * row4I[1]) + 0.5f;
|
|
|
|
outI[2] = (ma_mb * row1I[2] + a_mb * row3I[2] + ma_b * row2I[2] + a_b * row4I[2]) + 0.5f;
|
|
|
|
outI[3] = (ma_mb * row1I[3] + a_mb * row3I[3] + ma_b * row2I[3] + a_b * row4I[3]) + 0.5f;
|
2007-07-10 19:13:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
void bilinear_interpolation(ImBuf *in, ImBuf *out, float u, float v, int xout, int yout)
|
|
|
|
{
|
|
|
|
unsigned char *outI = NULL;
|
|
|
|
float *outF = NULL;
|
|
|
|
|
2012-10-01 06:18:45 +00:00
|
|
|
if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) {
|
|
|
|
return;
|
|
|
|
}
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
2008-11-20 00:34:24 +00:00
|
|
|
pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
|
|
|
bilinear_interpolation_color(in, outI, outF, u, v);
|
|
|
|
}
|
|
|
|
|
2007-07-10 19:13:03 +00:00
|
|
|
/* function assumes out to be zero'ed, only does RGBA */
|
|
|
|
/* NEAREST INTERPOLATION */
|
2012-12-11 14:19:41 +00:00
|
|
|
void nearest_interpolation_color(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
|
2007-07-10 19:13:03 +00:00
|
|
|
{
|
2014-04-27 00:24:11 +10:00
|
|
|
const float *dataF;
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
unsigned char *dataI;
|
2007-07-10 19:13:03 +00:00
|
|
|
int y1, x1;
|
|
|
|
|
2010-07-17 18:08:14 +00:00
|
|
|
/* ImBuf in must have a valid rect or rect_float, assume this is already checked */
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
2012-05-13 22:05:51 +00:00
|
|
|
x1 = (int)(u);
|
|
|
|
y1 = (int)(v);
|
2007-07-10 19:13:03 +00:00
|
|
|
|
2012-07-07 22:51:57 +00:00
|
|
|
/* sample area entirely outside image? */
|
2012-10-01 06:18:45 +00:00
|
|
|
if (x1 < 0 || x1 > in->x - 1 || y1 < 0 || y1 > in->y - 1) {
|
Fix for interpolation errors on lower-left borders in compositor image
inputs.
http://wiki.blender.org/uploads/4/4c/Compo_image_interpolation_borders.png
Problem is that all image buffer reader nodes (RenderLayer, Image,
MovieClip) were clipping pixel coordinates to 0..N range (N being width
or height respectively). Bilinear interpolation works ok then on the
upper-right borders (x, N) and (N, y), since the last (N-1) pixel fades
out to N (background). But the lower-left (x, 0) and (0, y) borders are
not correctly interpolated because the nodes cut off the negative pixels
before the interpolation function can calculate their value.
To fix this, the interpolation functions are now entirely responsible
for handling "out of range" cases, i.e. setting (0,0,0,0) results for
invalid pixels, while also handling interpolation for borders.
Callers should not do pixel range checks themselves, which also makes
the code simpler. Should not have any real performance penalty,
the interpolation functions do this check anyway, so is probably even
slightly faster.
2013-12-04 11:56:36 +01:00
|
|
|
if (outI)
|
|
|
|
outI[0] = outI[1] = outI[2] = outI[3] = 0;
|
|
|
|
if (outF)
|
|
|
|
outF[0] = outF[1] = outF[2] = outF[3] = 0.0f;
|
2012-10-01 06:18:45 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-07-07 22:51:57 +00:00
|
|
|
|
|
|
|
/* sample including outside of edges of image */
|
2012-05-13 22:05:51 +00:00
|
|
|
if (x1 < 0 || y1 < 0) {
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
if (outI) {
|
2012-05-13 22:05:51 +00:00
|
|
|
outI[0] = 0;
|
|
|
|
outI[1] = 0;
|
|
|
|
outI[2] = 0;
|
|
|
|
outI[3] = 0;
|
2007-07-10 19:13:03 +00:00
|
|
|
}
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
if (outF) {
|
2012-05-13 22:05:51 +00:00
|
|
|
outF[0] = 0.0f;
|
|
|
|
outF[1] = 0.0f;
|
|
|
|
outF[2] = 0.0f;
|
|
|
|
outF[3] = 0.0f;
|
2007-07-10 19:13:03 +00:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
else {
|
2015-05-29 13:38:20 +02:00
|
|
|
dataI = (unsigned char *)in->rect + ((size_t)in->x) * y1 * 4 + 4 * x1;
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
if (outI) {
|
2012-05-13 22:05:51 +00:00
|
|
|
outI[0] = dataI[0];
|
|
|
|
outI[1] = dataI[1];
|
|
|
|
outI[2] = dataI[2];
|
|
|
|
outI[3] = dataI[3];
|
2007-07-10 19:13:03 +00:00
|
|
|
}
|
2015-05-29 13:38:20 +02:00
|
|
|
dataF = in->rect_float + ((size_t)in->x) * y1 * 4 + 4 * x1;
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
if (outF) {
|
2012-05-13 22:05:51 +00:00
|
|
|
outF[0] = dataF[0];
|
|
|
|
outF[1] = dataF[1];
|
|
|
|
outF[2] = dataF[2];
|
|
|
|
outF[3] = dataF[3];
|
2007-07-10 19:13:03 +00:00
|
|
|
}
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2007-07-10 19:13:03 +00:00
|
|
|
}
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
2015-05-29 13:38:20 +02:00
|
|
|
|
|
|
|
void nearest_interpolation_color_wrap(struct ImBuf *in, unsigned char outI[4], float outF[4], float u, float v)
|
|
|
|
{
|
|
|
|
const float *dataF;
|
|
|
|
unsigned char *dataI;
|
|
|
|
int y, x;
|
|
|
|
|
|
|
|
/* ImBuf in must have a valid rect or rect_float, assume this is already checked */
|
|
|
|
|
|
|
|
x = (int) floor(u);
|
|
|
|
y = (int) floor(v);
|
|
|
|
|
|
|
|
x = x % in->x;
|
|
|
|
y = y % in->y;
|
|
|
|
|
|
|
|
/* wrap interpolation pixels - main difference from nearest_interpolation_color */
|
|
|
|
if (x < 0) x += in->x;
|
|
|
|
if (y < 0) y += in->y;
|
|
|
|
|
|
|
|
dataI = (unsigned char *)in->rect + ((size_t)in->x) * y * 4 + 4 * x;
|
|
|
|
if (outI) {
|
|
|
|
outI[0] = dataI[0];
|
|
|
|
outI[1] = dataI[1];
|
|
|
|
outI[2] = dataI[2];
|
|
|
|
outI[3] = dataI[3];
|
|
|
|
}
|
|
|
|
dataF = in->rect_float + ((size_t)in->x) * y * 4 + 4 * x;
|
|
|
|
if (outF) {
|
|
|
|
outF[0] = dataF[0];
|
|
|
|
outF[1] = dataF[1];
|
|
|
|
outF[2] = dataF[2];
|
|
|
|
outF[3] = dataF[3];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-11 14:19:41 +00:00
|
|
|
void nearest_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
{
|
|
|
|
unsigned char *outI = NULL;
|
|
|
|
float *outF = NULL;
|
|
|
|
|
2012-10-01 06:18:45 +00:00
|
|
|
if (in == NULL || (in->rect == NULL && in->rect_float == NULL)) {
|
|
|
|
return;
|
|
|
|
}
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
2008-11-20 00:34:24 +00:00
|
|
|
pixel_from_buffer(out, &outI, &outF, xout, yout); /* gcc warns these could be uninitialized, but its ok */
|
Split up the following imbuf functions in 2...
void bicubic_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void neareast_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
void bilinear_interpolation(struct ImBuf *in, struct ImBuf *out, float u, float v, int xout, int yout);
Added...
void bicubic_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void neareast_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
void bilinear_interpolation_color(struct ImBuf *in, unsigned char *col, float *col_float, float u, float v);
This is needed so for projection painting but generally useful if you want to get the interpolated color of a pixel in an image without having a destination imbuf.
While editing these I noticed the functons are a bit dodgy, they assume the input ImBuf has matching float/chr buffer to the output.
2008-11-19 03:28:07 +00:00
|
|
|
|
2012-12-11 14:19:41 +00:00
|
|
|
nearest_interpolation_color(in, outI, outF, x, y);
|
2008-11-20 00:34:24 +00:00
|
|
|
}
|
2012-08-07 16:47:46 +00:00
|
|
|
|
|
|
|
/*********************** Threaded image processing *************************/
|
|
|
|
|
2015-12-21 13:00:06 +11:00
|
|
|
static void processor_apply_func(TaskPool * __restrict pool, void *taskdata, int UNUSED(threadid))
|
2013-12-25 20:32:13 +06:00
|
|
|
{
|
|
|
|
void (*do_thread) (void *) = (void (*) (void *)) BLI_task_pool_userdata(pool);
|
|
|
|
do_thread(taskdata);
|
|
|
|
}
|
|
|
|
|
2012-08-07 16:47:46 +00:00
|
|
|
void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_customdata,
|
|
|
|
void (init_handle) (void *handle, int start_line, int tot_line,
|
|
|
|
void *customdata),
|
|
|
|
void *(do_thread) (void *))
|
|
|
|
{
|
2013-12-25 20:32:13 +06:00
|
|
|
const int lines_per_task = 64;
|
|
|
|
|
|
|
|
TaskScheduler *task_scheduler = BLI_task_scheduler_get();
|
|
|
|
TaskPool *task_pool;
|
2012-08-07 16:47:46 +00:00
|
|
|
|
2013-12-25 20:32:13 +06:00
|
|
|
void *handles;
|
|
|
|
int total_tasks = (buffer_lines + lines_per_task - 1) / lines_per_task;
|
|
|
|
int i, start_line;
|
2012-08-07 16:47:46 +00:00
|
|
|
|
2013-12-25 20:32:13 +06:00
|
|
|
task_pool = BLI_task_pool_create(task_scheduler, do_thread);
|
2012-08-07 16:47:46 +00:00
|
|
|
|
2013-12-25 20:32:13 +06:00
|
|
|
handles = MEM_callocN(handle_size * total_tasks, "processor apply threaded handles");
|
2012-08-07 16:47:46 +00:00
|
|
|
|
|
|
|
start_line = 0;
|
|
|
|
|
2013-12-25 20:32:13 +06:00
|
|
|
for (i = 0; i < total_tasks; i++) {
|
|
|
|
int lines_per_current_task;
|
2012-08-07 16:47:46 +00:00
|
|
|
void *handle = ((char *) handles) + handle_size * i;
|
|
|
|
|
2013-12-25 20:32:13 +06:00
|
|
|
if (i < total_tasks - 1)
|
|
|
|
lines_per_current_task = lines_per_task;
|
2012-08-07 16:47:46 +00:00
|
|
|
else
|
2013-12-25 20:32:13 +06:00
|
|
|
lines_per_current_task = buffer_lines - start_line;
|
2012-08-07 16:47:46 +00:00
|
|
|
|
2013-12-25 20:32:13 +06:00
|
|
|
init_handle(handle, start_line, lines_per_current_task, init_customdata);
|
2012-08-07 16:47:46 +00:00
|
|
|
|
2013-12-25 20:32:13 +06:00
|
|
|
BLI_task_pool_push(task_pool, processor_apply_func, handle, false, TASK_PRIORITY_LOW);
|
2012-08-07 16:47:46 +00:00
|
|
|
|
2013-12-25 20:32:13 +06:00
|
|
|
start_line += lines_per_task;
|
2012-08-07 16:47:46 +00:00
|
|
|
}
|
|
|
|
|
2013-12-25 20:32:13 +06:00
|
|
|
/* work and wait until tasks are done */
|
|
|
|
BLI_task_pool_work_and_wait(task_pool);
|
2012-08-07 16:47:46 +00:00
|
|
|
|
2013-12-25 20:32:13 +06:00
|
|
|
/* Free memory. */
|
2016-05-05 13:15:51 +02:00
|
|
|
MEM_freeN(handles);
|
|
|
|
BLI_task_pool_free(task_pool);
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct ScanlineGlobalData {
|
|
|
|
void *custom_data;
|
|
|
|
ScanlineThreadFunc do_thread;
|
2016-05-05 14:18:11 +02:00
|
|
|
int scanlines_per_task;
|
|
|
|
int total_scanlines;
|
2016-05-05 13:15:51 +02:00
|
|
|
} ScanlineGlobalData;
|
|
|
|
|
|
|
|
typedef struct ScanlineTask {
|
|
|
|
int start_scanline;
|
|
|
|
int num_scanlines;
|
|
|
|
} ScanlineTask;
|
|
|
|
|
|
|
|
static void processor_apply_scanline_func(TaskPool * __restrict pool,
|
|
|
|
void *taskdata,
|
|
|
|
int UNUSED(threadid))
|
|
|
|
{
|
2016-05-06 06:29:39 +10:00
|
|
|
ScanlineGlobalData *data = BLI_task_pool_userdata(pool);
|
2016-05-05 14:18:11 +02:00
|
|
|
int start_scanline = GET_INT_FROM_POINTER(taskdata);
|
|
|
|
int num_scanlines = min_ii(data->scanlines_per_task,
|
|
|
|
data->total_scanlines - start_scanline);
|
2016-05-05 13:15:51 +02:00
|
|
|
data->do_thread(data->custom_data,
|
2016-05-05 14:18:11 +02:00
|
|
|
start_scanline,
|
|
|
|
num_scanlines);
|
2016-05-05 13:15:51 +02:00
|
|
|
}
|
|
|
|
|
2016-05-05 14:18:11 +02:00
|
|
|
void IMB_processor_apply_threaded_scanlines(int total_scanlines,
|
2016-05-05 13:15:51 +02:00
|
|
|
ScanlineThreadFunc do_thread,
|
|
|
|
void *custom_data)
|
|
|
|
{
|
2016-05-05 14:18:11 +02:00
|
|
|
const int scanlines_per_task = 64;
|
2016-05-05 13:15:51 +02:00
|
|
|
ScanlineGlobalData data;
|
|
|
|
data.custom_data = custom_data;
|
|
|
|
data.do_thread = do_thread;
|
2016-05-05 14:18:11 +02:00
|
|
|
data.scanlines_per_task = scanlines_per_task;
|
|
|
|
data.total_scanlines = total_scanlines;
|
|
|
|
const int total_tasks = (total_scanlines + scanlines_per_task - 1) / scanlines_per_task;
|
2016-05-05 13:15:51 +02:00
|
|
|
TaskScheduler *task_scheduler = BLI_task_scheduler_get();
|
|
|
|
TaskPool *task_pool = BLI_task_pool_create(task_scheduler, &data);
|
|
|
|
for (int i = 0, start_line = 0; i < total_tasks; i++) {
|
|
|
|
BLI_task_pool_push(task_pool,
|
|
|
|
processor_apply_scanline_func,
|
2016-05-05 14:18:11 +02:00
|
|
|
SET_INT_IN_POINTER(start_line),
|
2016-05-05 13:15:51 +02:00
|
|
|
false,
|
|
|
|
TASK_PRIORITY_LOW);
|
2016-05-05 14:18:11 +02:00
|
|
|
start_line += scanlines_per_task;
|
2016-05-05 13:15:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* work and wait until tasks are done */
|
|
|
|
BLI_task_pool_work_and_wait(task_pool);
|
|
|
|
|
|
|
|
/* Free memory. */
|
2013-12-25 20:32:13 +06:00
|
|
|
BLI_task_pool_free(task_pool);
|
2012-08-07 16:47:46 +00:00
|
|
|
}
|
2013-01-05 15:33:18 +00:00
|
|
|
|
|
|
|
/* Alpha-under */
|
|
|
|
|
|
|
|
void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3])
|
|
|
|
{
|
2015-04-30 12:10:58 +02:00
|
|
|
size_t a = ((size_t)x) * y;
|
2013-01-05 15:33:18 +00:00
|
|
|
float *fp = rect_float;
|
|
|
|
|
|
|
|
while (a--) {
|
|
|
|
if (fp[3] == 0.0f) {
|
|
|
|
copy_v3_v3(fp, backcol);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
float mul = 1.0f - fp[3];
|
|
|
|
|
|
|
|
fp[0] += mul * backcol[0];
|
|
|
|
fp[1] += mul * backcol[1];
|
|
|
|
fp[2] += mul * backcol[2];
|
|
|
|
}
|
|
|
|
|
|
|
|
fp[3] = 1.0f;
|
|
|
|
|
|
|
|
fp += 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IMB_alpha_under_color_byte(unsigned char *rect, int x, int y, float backcol[3])
|
|
|
|
{
|
2015-04-30 12:10:58 +02:00
|
|
|
size_t a = ((size_t)x) * y;
|
2013-01-05 15:33:18 +00:00
|
|
|
unsigned char *cp = rect;
|
|
|
|
|
|
|
|
while (a--) {
|
2013-08-23 08:27:01 +00:00
|
|
|
if (cp[3] == 255) {
|
|
|
|
/* pass */
|
|
|
|
}
|
|
|
|
else if (cp[3] == 0) {
|
2013-01-05 15:33:18 +00:00
|
|
|
cp[0] = backcol[0] * 255;
|
|
|
|
cp[1] = backcol[1] * 255;
|
|
|
|
cp[2] = backcol[2] * 255;
|
|
|
|
}
|
|
|
|
else {
|
2013-08-23 08:27:01 +00:00
|
|
|
float alpha = cp[3] / 255.0;
|
|
|
|
float mul = 1.0f - alpha;
|
2013-01-05 15:33:18 +00:00
|
|
|
|
2013-08-23 08:27:01 +00:00
|
|
|
cp[0] = (cp[0] * alpha) + mul * backcol[0];
|
|
|
|
cp[1] = (cp[1] * alpha) + mul * backcol[1];
|
|
|
|
cp[2] = (cp[2] * alpha) + mul * backcol[2];
|
2013-01-05 15:33:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cp[3] = 255;
|
|
|
|
|
|
|
|
cp += 4;
|
|
|
|
}
|
|
|
|
}
|