2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-01-12 19:02:08 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* 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.
|
2009-01-12 19:02:08 +00:00
|
|
|
*
|
|
|
|
|
* Author: Peter Schlaile < peter [at] schlaile [dot] de >
|
|
|
|
|
*
|
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2011-02-27 20:29:51 +00:00
|
|
|
/** \file blender/editors/space_sequencer/sequencer_scopes.c
|
|
|
|
|
* \ingroup spseq
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2009-01-12 19:02:08 +00:00
|
|
|
#include <math.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2012-01-14 17:14:23 +00:00
|
|
|
#include "BLI_math_color.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
|
2009-01-12 19:02:08 +00:00
|
|
|
#include "IMB_imbuf_types.h"
|
|
|
|
|
#include "IMB_imbuf.h"
|
|
|
|
|
|
|
|
|
|
#include "sequencer_intern.h"
|
|
|
|
|
|
2012-01-14 17:14:23 +00:00
|
|
|
/* XXX, why is this function better then BLI_math version?
|
|
|
|
|
* only difference is it does some normalize after, need to double check on this - campbell */
|
|
|
|
|
static void rgb_to_yuv_normalized(const float rgb[3], float yuv[3])
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
yuv[0] = 0.299f * rgb[0] + 0.587f * rgb[1] + 0.114f * rgb[2];
|
|
|
|
|
yuv[1] = 0.492f * (rgb[2] - yuv[0]);
|
|
|
|
|
yuv[2] = 0.877f * (rgb[0] - yuv[0]);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
/* Normalize */
|
|
|
|
|
yuv[1] *= 255.0f / (122 * 2.0f);
|
|
|
|
|
yuv[1] += 0.5f;
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
yuv[2] *= 255.0f / (157 * 2.0f);
|
|
|
|
|
yuv[2] += 0.5f;
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static void scope_put_pixel(unsigned char *table, unsigned char *pos)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
char newval = table[*pos];
|
|
|
|
|
pos[0] = pos[1] = pos[2] = newval;
|
|
|
|
|
pos[3] = 255;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-27 09:01:35 +00:00
|
|
|
static void scope_put_pixel_single(unsigned char *table, unsigned char *pos, int col)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
char newval = table[pos[col]];
|
|
|
|
|
pos[col] = newval;
|
|
|
|
|
pos[3] = 255;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-27 09:01:35 +00:00
|
|
|
static void wform_put_line(int w, unsigned char *last_pos, unsigned char *new_pos)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
if (last_pos > new_pos) {
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *temp = new_pos;
|
2009-01-12 19:02:08 +00:00
|
|
|
new_pos = last_pos;
|
|
|
|
|
last_pos = temp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (last_pos < new_pos) {
|
|
|
|
|
if (last_pos[0] == 0) {
|
|
|
|
|
last_pos[0] = last_pos[1] = last_pos[2] = 32;
|
|
|
|
|
last_pos[3] = 255;
|
|
|
|
|
}
|
2012-03-29 22:26:11 +00:00
|
|
|
last_pos += 4 * w;
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-27 09:01:35 +00:00
|
|
|
static void wform_put_line_single(int w, unsigned char *last_pos, unsigned char *new_pos, int col)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
if (last_pos > new_pos) {
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *temp = new_pos;
|
2009-01-12 19:02:08 +00:00
|
|
|
new_pos = last_pos;
|
|
|
|
|
last_pos = temp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (last_pos < new_pos) {
|
|
|
|
|
if (last_pos[col] == 0) {
|
|
|
|
|
last_pos[col] = 32;
|
|
|
|
|
last_pos[3] = 255;
|
|
|
|
|
}
|
2012-03-29 22:26:11 +00:00
|
|
|
last_pos += 4 * w;
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static void wform_put_border(unsigned char *tgt, int w, int h)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < w; x++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *p = tgt + 4 * x;
|
2009-01-12 19:02:08 +00:00
|
|
|
p[1] = p[3] = 255.0;
|
|
|
|
|
p[4 * w + 1] = p[4 * w + 3] = 255.0;
|
|
|
|
|
p = tgt + 4 * (w * (h - 1) + x);
|
|
|
|
|
p[1] = p[3] = 255.0;
|
|
|
|
|
p[-4 * w + 1] = p[-4 * w + 3] = 255.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < h; y++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *p = tgt + 4 * w * y;
|
2009-01-12 19:02:08 +00:00
|
|
|
p[1] = p[3] = 255.0;
|
|
|
|
|
p[4 + 1] = p[4 + 3] = 255.0;
|
|
|
|
|
p = tgt + 4 * (w * y + w - 1);
|
|
|
|
|
p[1] = p[3] = 255.0;
|
|
|
|
|
p[-4 + 1] = p[-4 + 3] = 255.0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static void wform_put_gridrow(unsigned char *tgt, float perc, int w, int h)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
tgt += (int) (perc / 100.0f * h) * w * 4;
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
for (i = 0; i < w * 2; i++) {
|
2009-01-12 19:02:08 +00:00
|
|
|
tgt[0] = 255;
|
|
|
|
|
|
|
|
|
|
tgt += 4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static void wform_put_grid(unsigned char *tgt, int w, int h)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
wform_put_gridrow(tgt, 90.0, w, h);
|
|
|
|
|
wform_put_gridrow(tgt, 70.0, w, h);
|
|
|
|
|
wform_put_gridrow(tgt, 10.0, w, h);
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static ImBuf *make_waveform_view_from_ibuf_byte(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
|
|
|
|
|
int x, y;
|
|
|
|
|
unsigned char *src = (unsigned char *) ibuf->rect;
|
|
|
|
|
unsigned char *tgt = (unsigned char *) rval->rect;
|
2009-01-12 19:02:08 +00:00
|
|
|
int w = ibuf->x + 3;
|
|
|
|
|
int h = 515;
|
|
|
|
|
float waveform_gamma = 0.2;
|
|
|
|
|
unsigned char wtable[256];
|
|
|
|
|
|
|
|
|
|
wform_put_grid(tgt, w, h);
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < 256; x++) {
|
2012-08-27 09:01:35 +00:00
|
|
|
wtable[x] = (unsigned char) (pow(((float) x + 1) / 256, waveform_gamma) * 255);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < ibuf->y; y++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *last_p = NULL;
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
for (x = 0; x < ibuf->x; x++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *rgb = src + 4 * (ibuf->x * y + x);
|
2012-02-04 06:55:29 +00:00
|
|
|
float v = (float)rgb_to_luma_byte(rgb) / 255.0f;
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *p = tgt;
|
2009-01-12 19:02:08 +00:00
|
|
|
p += 4 * (w * ((int) (v * (h - 3)) + 1) + x + 1);
|
|
|
|
|
|
|
|
|
|
scope_put_pixel(wtable, p);
|
|
|
|
|
p += 4 * w;
|
|
|
|
|
scope_put_pixel(wtable, p);
|
|
|
|
|
|
2011-04-03 10:04:16 +00:00
|
|
|
if (last_p != NULL) {
|
2009-01-12 19:02:08 +00:00
|
|
|
wform_put_line(w, last_p, p);
|
|
|
|
|
}
|
|
|
|
|
last_p = p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wform_put_border(tgt, w, h);
|
|
|
|
|
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static ImBuf *make_waveform_view_from_ibuf_float(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
|
|
|
|
|
int x, y;
|
|
|
|
|
float *src = ibuf->rect_float;
|
|
|
|
|
unsigned char *tgt = (unsigned char *) rval->rect;
|
2009-01-12 19:02:08 +00:00
|
|
|
int w = ibuf->x + 3;
|
|
|
|
|
int h = 515;
|
|
|
|
|
float waveform_gamma = 0.2;
|
|
|
|
|
unsigned char wtable[256];
|
|
|
|
|
|
|
|
|
|
wform_put_grid(tgt, w, h);
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < 256; x++) {
|
2012-08-27 09:01:35 +00:00
|
|
|
wtable[x] = (unsigned char) (pow(((float) x + 1) / 256, waveform_gamma) * 255);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < ibuf->y; y++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *last_p = NULL;
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
for (x = 0; x < ibuf->x; x++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
float *rgb = src + 4 * (ibuf->x * y + x);
|
2012-01-14 17:14:23 +00:00
|
|
|
float v = rgb_to_luma(rgb);
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *p = tgt;
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2011-03-30 05:07:12 +00:00
|
|
|
CLAMP(v, 0.0f, 1.0f);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
p += 4 * (w * ((int) (v * (h - 3)) + 1) + x + 1);
|
|
|
|
|
|
|
|
|
|
scope_put_pixel(wtable, p);
|
|
|
|
|
p += 4 * w;
|
|
|
|
|
scope_put_pixel(wtable, p);
|
|
|
|
|
|
2011-04-03 10:04:16 +00:00
|
|
|
if (last_p != NULL) {
|
2009-01-12 19:02:08 +00:00
|
|
|
wform_put_line(w, last_p, p);
|
|
|
|
|
}
|
|
|
|
|
last_p = p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wform_put_border(tgt, w, h);
|
|
|
|
|
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *make_waveform_view_from_ibuf(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
if (ibuf->rect_float) {
|
|
|
|
|
return make_waveform_view_from_ibuf_float(ibuf);
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2009-01-12 19:02:08 +00:00
|
|
|
return make_waveform_view_from_ibuf_byte(ibuf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-04-21 12:51:47 +00:00
|
|
|
static ImBuf *make_sep_waveform_view_from_ibuf_byte(ImBuf *ibuf)
|
|
|
|
|
{
|
2012-08-27 09:01:35 +00:00
|
|
|
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
|
2012-03-29 22:26:11 +00:00
|
|
|
int x, y;
|
|
|
|
|
unsigned char *src = (unsigned char *) ibuf->rect;
|
|
|
|
|
unsigned char *tgt = (unsigned char *) rval->rect;
|
2009-01-12 19:02:08 +00:00
|
|
|
int w = ibuf->x + 3;
|
2012-03-29 22:26:11 +00:00
|
|
|
int sw = ibuf->x / 3;
|
2009-01-12 19:02:08 +00:00
|
|
|
int h = 515;
|
|
|
|
|
float waveform_gamma = 0.2;
|
|
|
|
|
unsigned char wtable[256];
|
|
|
|
|
|
|
|
|
|
wform_put_grid(tgt, w, h);
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < 256; x++) {
|
2012-08-27 09:01:35 +00:00
|
|
|
wtable[x] = (unsigned char) (pow(((float) x + 1) / 256, waveform_gamma) * 255);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < ibuf->y; y++) {
|
2011-04-03 10:04:16 +00:00
|
|
|
unsigned char *last_p[3] = {NULL, NULL, NULL};
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
for (x = 0; x < ibuf->x; x++) {
|
|
|
|
|
int c;
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *rgb = src + 4 * (ibuf->x * y + x);
|
2009-01-12 19:02:08 +00:00
|
|
|
for (c = 0; c < 3; c++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *p = tgt;
|
2012-08-27 09:01:35 +00:00
|
|
|
p += 4 * (w * ((rgb[c] * (h - 3)) / 255 + 1) + c * sw + x / 3 + 1);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
scope_put_pixel_single(wtable, p, c);
|
|
|
|
|
p += 4 * w;
|
|
|
|
|
scope_put_pixel_single(wtable, p, c);
|
|
|
|
|
|
2011-04-03 10:04:16 +00:00
|
|
|
if (last_p[c] != NULL) {
|
2012-08-27 09:01:35 +00:00
|
|
|
wform_put_line_single(w, last_p[c], p, c);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
last_p[c] = p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wform_put_border(tgt, w, h);
|
|
|
|
|
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static ImBuf *make_sep_waveform_view_from_ibuf_float(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect);
|
|
|
|
|
int x, y;
|
|
|
|
|
float *src = ibuf->rect_float;
|
|
|
|
|
unsigned char *tgt = (unsigned char *) rval->rect;
|
2009-01-12 19:02:08 +00:00
|
|
|
int w = ibuf->x + 3;
|
2012-03-29 22:26:11 +00:00
|
|
|
int sw = ibuf->x / 3;
|
2009-01-12 19:02:08 +00:00
|
|
|
int h = 515;
|
|
|
|
|
float waveform_gamma = 0.2;
|
|
|
|
|
unsigned char wtable[256];
|
|
|
|
|
|
|
|
|
|
wform_put_grid(tgt, w, h);
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < 256; x++) {
|
2012-08-27 09:01:35 +00:00
|
|
|
wtable[x] = (unsigned char) (pow(((float) x + 1) / 256, waveform_gamma) * 255);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < ibuf->y; y++) {
|
2011-04-03 10:04:16 +00:00
|
|
|
unsigned char *last_p[3] = {NULL, NULL, NULL};
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
for (x = 0; x < ibuf->x; x++) {
|
|
|
|
|
int c;
|
2012-03-29 22:26:11 +00:00
|
|
|
float *rgb = src + 4 * (ibuf->x * y + x);
|
2009-01-12 19:02:08 +00:00
|
|
|
for (c = 0; c < 3; c++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *p = tgt;
|
2009-01-12 19:02:08 +00:00
|
|
|
float v = rgb[c];
|
|
|
|
|
|
2011-03-30 05:07:12 +00:00
|
|
|
CLAMP(v, 0.0f, 1.0f);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2012-08-27 09:01:35 +00:00
|
|
|
p += 4 * (w * ((int) (v * (h - 3)) + 1) + c * sw + x / 3 + 1);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
scope_put_pixel_single(wtable, p, c);
|
|
|
|
|
p += 4 * w;
|
|
|
|
|
scope_put_pixel_single(wtable, p, c);
|
|
|
|
|
|
2011-04-03 10:04:16 +00:00
|
|
|
if (last_p[c] != NULL) {
|
2012-08-27 09:01:35 +00:00
|
|
|
wform_put_line_single(w, last_p[c], p, c);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
last_p[c] = p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wform_put_border(tgt, w, h);
|
|
|
|
|
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *make_sep_waveform_view_from_ibuf(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
if (ibuf->rect_float) {
|
|
|
|
|
return make_sep_waveform_view_from_ibuf_float(ibuf);
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2009-01-12 19:02:08 +00:00
|
|
|
return make_sep_waveform_view_from_ibuf_byte(ibuf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static void draw_zebra_byte(ImBuf *src, ImBuf *ibuf, float perc)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2011-03-30 05:07:12 +00:00
|
|
|
unsigned int limit = 255.0f * perc / 100.0f;
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *p = (unsigned char *) src->rect;
|
|
|
|
|
unsigned char *o = (unsigned char *) ibuf->rect;
|
2009-01-12 19:02:08 +00:00
|
|
|
int x;
|
|
|
|
|
int y;
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < ibuf->y; y++) {
|
|
|
|
|
for (x = 0; x < ibuf->x; x++) {
|
|
|
|
|
unsigned char r = *p++;
|
|
|
|
|
unsigned char g = *p++;
|
|
|
|
|
unsigned char b = *p++;
|
|
|
|
|
unsigned char a = *p++;
|
|
|
|
|
|
|
|
|
|
if (r >= limit || g >= limit || b >= limit) {
|
|
|
|
|
if (((x + y) & 0x08) != 0) {
|
|
|
|
|
r = 255 - r;
|
|
|
|
|
g = 255 - g;
|
|
|
|
|
b = 255 - b;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*o++ = r;
|
|
|
|
|
*o++ = g;
|
|
|
|
|
*o++ = b;
|
|
|
|
|
*o++ = a;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static void draw_zebra_float(ImBuf *src, ImBuf *ibuf, float perc)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2011-03-30 05:07:12 +00:00
|
|
|
float limit = perc / 100.0f;
|
2012-03-29 22:26:11 +00:00
|
|
|
float *p = src->rect_float;
|
|
|
|
|
unsigned char *o = (unsigned char *) ibuf->rect;
|
2009-01-12 19:02:08 +00:00
|
|
|
int x;
|
|
|
|
|
int y;
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < ibuf->y; y++) {
|
|
|
|
|
for (x = 0; x < ibuf->x; x++) {
|
|
|
|
|
float r = *p++;
|
|
|
|
|
float g = *p++;
|
|
|
|
|
float b = *p++;
|
|
|
|
|
float a = *p++;
|
|
|
|
|
|
|
|
|
|
if (r >= limit || g >= limit || b >= limit) {
|
|
|
|
|
if (((x + y) & 0x08) != 0) {
|
|
|
|
|
r = -r;
|
|
|
|
|
g = -g;
|
|
|
|
|
b = -b;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*o++ = FTOCHAR(r);
|
|
|
|
|
*o++ = FTOCHAR(g);
|
|
|
|
|
*o++ = FTOCHAR(b);
|
|
|
|
|
*o++ = FTOCHAR(a);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *make_zebra_view_from_ibuf(ImBuf *src, float perc)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *ibuf = IMB_allocImBuf(src->x, src->y, 32, IB_rect);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
if (src->rect_float) {
|
|
|
|
|
draw_zebra_float(src, ibuf, perc);
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2009-01-12 19:02:08 +00:00
|
|
|
draw_zebra_byte(src, ibuf, perc);
|
|
|
|
|
}
|
|
|
|
|
return ibuf;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static void draw_histogram_marker(ImBuf *ibuf, int x)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *p = (unsigned char *) ibuf->rect;
|
2009-01-12 19:02:08 +00:00
|
|
|
int barh = ibuf->y * 0.1;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
p += 4 * (x + ibuf->x * (ibuf->y - barh + 1));
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
for (i = 0; i < barh - 1; i++) {
|
2009-01-12 19:02:08 +00:00
|
|
|
p[0] = p[1] = p[2] = 255;
|
|
|
|
|
p += ibuf->x * 4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static void draw_histogram_bar(ImBuf *ibuf, int x, float val, int col)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *p = (unsigned char *) ibuf->rect;
|
2011-03-30 05:07:12 +00:00
|
|
|
int barh = ibuf->y * val * 0.9f;
|
2009-01-12 19:02:08 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
p += 4 * (x + ibuf->x);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < barh; i++) {
|
|
|
|
|
p[col] = 255;
|
|
|
|
|
p += ibuf->x * 4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static ImBuf *make_histogram_view_from_ibuf_byte(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *rval = IMB_allocImBuf(515, 128, 32, IB_rect);
|
|
|
|
|
int c, x, y;
|
2011-02-27 08:31:10 +00:00
|
|
|
unsigned int n;
|
2012-03-29 22:26:11 +00:00
|
|
|
unsigned char *src = (unsigned char *) ibuf->rect;
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
unsigned int bins[3][256];
|
|
|
|
|
|
2012-08-27 09:01:34 +00:00
|
|
|
memset(bins, 0, sizeof(bins));
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
for (y = 0; y < ibuf->y; y++) {
|
|
|
|
|
for (x = 0; x < ibuf->x; x++) {
|
|
|
|
|
bins[0][*src++]++;
|
|
|
|
|
bins[1][*src++]++;
|
|
|
|
|
bins[2][*src++]++;
|
|
|
|
|
src++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
for (c = 0; c < 3; c++) {
|
|
|
|
|
for (x = 0; x < 256; x++) {
|
|
|
|
|
if (bins[c][x] > n) {
|
|
|
|
|
n = bins[c][x];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (c = 0; c < 3; c++) {
|
|
|
|
|
for (x = 0; x < 256; x++) {
|
2012-08-27 09:01:35 +00:00
|
|
|
draw_histogram_bar(rval, x * 2 + 1, ((float) bins[c][x]) / n, c);
|
|
|
|
|
draw_histogram_bar(rval, x * 2 + 2, ((float) bins[c][x]) / n, c);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
wform_put_border((unsigned char *) rval->rect, rval->x, rval->y);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int get_bin_float(float f)
|
|
|
|
|
{
|
2011-03-30 05:07:12 +00:00
|
|
|
if (f < -0.25f) {
|
2012-08-27 09:01:34 +00:00
|
|
|
return 0;
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
2012-08-27 09:01:34 +00:00
|
|
|
else if (f >= 1.25f) {
|
|
|
|
|
return 511;
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
2011-03-30 05:07:12 +00:00
|
|
|
return (int) (((f + 0.25f) / 1.5f) * 512);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static ImBuf *make_histogram_view_from_ibuf_float(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *rval = IMB_allocImBuf(515, 128, 32, IB_rect);
|
|
|
|
|
int n, c, x, y;
|
|
|
|
|
float *src = ibuf->rect_float;
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
unsigned int bins[3][512];
|
|
|
|
|
|
2012-08-27 09:01:34 +00:00
|
|
|
memset(bins, 0, sizeof(bins));
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
for (y = 0; y < ibuf->y; y++) {
|
|
|
|
|
for (x = 0; x < ibuf->x; x++) {
|
|
|
|
|
bins[0][get_bin_float(*src++)]++;
|
|
|
|
|
bins[1][get_bin_float(*src++)]++;
|
|
|
|
|
bins[2][get_bin_float(*src++)]++;
|
|
|
|
|
src++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
draw_histogram_marker(rval, get_bin_float(0.0));
|
|
|
|
|
draw_histogram_marker(rval, get_bin_float(1.0));
|
|
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
|
for (c = 0; c < 3; c++) {
|
|
|
|
|
for (x = 0; x < 512; x++) {
|
|
|
|
|
if (bins[c][x] > n) {
|
|
|
|
|
n = bins[c][x];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (c = 0; c < 3; c++) {
|
|
|
|
|
for (x = 0; x < 512; x++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
draw_histogram_bar(rval, x + 1, (float) bins[c][x] / n, c);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
wform_put_border((unsigned char *) rval->rect, rval->x, rval->y);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *make_histogram_view_from_ibuf(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
if (ibuf->rect_float) {
|
|
|
|
|
return make_histogram_view_from_ibuf_float(ibuf);
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2009-01-12 19:02:08 +00:00
|
|
|
return make_histogram_view_from_ibuf_byte(ibuf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-27 09:01:35 +00:00
|
|
|
static void vectorscope_put_cross(unsigned char r, unsigned char g, unsigned char b, char *tgt, int w, int h, int size)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
float rgb[3], yuv[3];
|
2012-03-29 22:26:11 +00:00
|
|
|
char *p;
|
2009-01-12 19:02:08 +00:00
|
|
|
int x = 0;
|
|
|
|
|
int y = 0;
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
rgb[0] = (float)r / 255.0f;
|
|
|
|
|
rgb[1] = (float)g / 255.0f;
|
|
|
|
|
rgb[2] = (float)b / 255.0f;
|
2012-01-14 17:14:23 +00:00
|
|
|
rgb_to_yuv_normalized(rgb, yuv);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2012-05-09 09:24:15 +00:00
|
|
|
p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) +
|
|
|
|
|
(int) ((yuv[1] * (w - 3) + 1)));
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
if (r == 0 && g == 0 && b == 0) {
|
|
|
|
|
r = 255;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (y = -size; y <= size; y++) {
|
|
|
|
|
for (x = -size; x <= size; x++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
char *q = p + 4 * (y * w + x);
|
2009-01-12 19:02:08 +00:00
|
|
|
q[0] = r; q[1] = g; q[2] = b; q[3] = 255;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static ImBuf *make_vectorscope_view_from_ibuf_byte(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *rval = IMB_allocImBuf(515, 515, 32, IB_rect);
|
|
|
|
|
int x, y;
|
|
|
|
|
char *src = (char *) ibuf->rect;
|
|
|
|
|
char *tgt = (char *) rval->rect;
|
2009-01-12 19:02:08 +00:00
|
|
|
float rgb[3], yuv[3];
|
|
|
|
|
int w = 515;
|
|
|
|
|
int h = 515;
|
|
|
|
|
float scope_gamma = 0.2;
|
|
|
|
|
unsigned char wtable[256];
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < 256; x++) {
|
2012-08-27 09:01:35 +00:00
|
|
|
wtable[x] = (unsigned char) (pow(((float) x + 1) / 256, scope_gamma) * 255);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (x = 0; x <= 255; x++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
vectorscope_put_cross(255, 0, 255 - x, tgt, w, h, 1);
|
|
|
|
|
vectorscope_put_cross(255, x, 0, tgt, w, h, 1);
|
|
|
|
|
vectorscope_put_cross(255 - x, 255, 0, tgt, w, h, 1);
|
2009-01-12 19:02:08 +00:00
|
|
|
vectorscope_put_cross(0, 255, x, tgt, w, h, 1);
|
|
|
|
|
vectorscope_put_cross(0, 255 - x, 255, tgt, w, h, 1);
|
|
|
|
|
vectorscope_put_cross(x, 0, 255, tgt, w, h, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < ibuf->y; y++) {
|
|
|
|
|
for (x = 0; x < ibuf->x; x++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
char *src1 = src + 4 * (ibuf->x * y + x);
|
|
|
|
|
char *p;
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
rgb[0] = (float)src1[0] / 255.0f;
|
|
|
|
|
rgb[1] = (float)src1[1] / 255.0f;
|
|
|
|
|
rgb[2] = (float)src1[2] / 255.0f;
|
2012-01-14 17:14:23 +00:00
|
|
|
rgb_to_yuv_normalized(rgb, yuv);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2012-05-09 09:24:15 +00:00
|
|
|
p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) +
|
|
|
|
|
(int) ((yuv[1] * (w - 3) + 1)));
|
2012-03-29 22:26:11 +00:00
|
|
|
scope_put_pixel(wtable, (unsigned char *)p);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vectorscope_put_cross(0, 0, 0, tgt, w, h, 3);
|
|
|
|
|
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *rval = IMB_allocImBuf(515, 515, 32, IB_rect);
|
|
|
|
|
int x, y;
|
|
|
|
|
float *src = ibuf->rect_float;
|
|
|
|
|
char *tgt = (char *) rval->rect;
|
2009-01-12 19:02:08 +00:00
|
|
|
float rgb[3], yuv[3];
|
|
|
|
|
int w = 515;
|
|
|
|
|
int h = 515;
|
|
|
|
|
float scope_gamma = 0.2;
|
|
|
|
|
unsigned char wtable[256];
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < 256; x++) {
|
2012-08-27 09:01:35 +00:00
|
|
|
wtable[x] = (unsigned char) (pow(((float) x + 1) / 256, scope_gamma) * 255);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (x = 0; x <= 255; x++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
vectorscope_put_cross(255, 0, 255 - x, tgt, w, h, 1);
|
|
|
|
|
vectorscope_put_cross(255, x, 0, tgt, w, h, 1);
|
|
|
|
|
vectorscope_put_cross(255 - x, 255, 0, tgt, w, h, 1);
|
2009-01-12 19:02:08 +00:00
|
|
|
vectorscope_put_cross(0, 255, x, tgt, w, h, 1);
|
|
|
|
|
vectorscope_put_cross(0, 255 - x, 255, tgt, w, h, 1);
|
|
|
|
|
vectorscope_put_cross(x, 0, 255, tgt, w, h, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < ibuf->y; y++) {
|
|
|
|
|
for (x = 0; x < ibuf->x; x++) {
|
2012-03-29 22:26:11 +00:00
|
|
|
float *src1 = src + 4 * (ibuf->x * y + x);
|
|
|
|
|
char *p;
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
memcpy(rgb, src1, 3 * sizeof(float));
|
|
|
|
|
|
2011-03-30 05:07:12 +00:00
|
|
|
CLAMP(rgb[0], 0.0f, 1.0f);
|
|
|
|
|
CLAMP(rgb[1], 0.0f, 1.0f);
|
|
|
|
|
CLAMP(rgb[2], 0.0f, 1.0f);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2012-01-14 17:14:23 +00:00
|
|
|
rgb_to_yuv_normalized(rgb, yuv);
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2012-05-09 09:24:15 +00:00
|
|
|
p = tgt + 4 * (w * (int) ((yuv[2] * (h - 3) + 1)) +
|
|
|
|
|
(int) ((yuv[1] * (w - 3) + 1)));
|
2012-03-29 22:26:11 +00:00
|
|
|
scope_put_pixel(wtable, (unsigned char *)p);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vectorscope_put_cross(0, 0, 0, tgt, w, h, 3);
|
|
|
|
|
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
ImBuf *make_vectorscope_view_from_ibuf(ImBuf *ibuf)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
|
|
|
|
if (ibuf->rect_float) {
|
|
|
|
|
return make_vectorscope_view_from_ibuf_float(ibuf);
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2009-01-12 19:02:08 +00:00
|
|
|
return make_vectorscope_view_from_ibuf_byte(ibuf);
|
|
|
|
|
}
|
|
|
|
|
}
|