Initial revision
This commit is contained in:
290
source/blender/imbuf/intern/ham.c
Normal file
290
source/blender/imbuf/intern/ham.c
Normal file
@@ -0,0 +1,290 @@
|
||||
/**
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* 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,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
* ham.c
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "imbuf.h"
|
||||
#include "imbuf_patch.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "IMB_cmap.h"
|
||||
#include "IMB_hamx.h"
|
||||
#include "IMB_ham.h"
|
||||
|
||||
extern short alpha_col0;
|
||||
|
||||
#define HAMB 0x0100
|
||||
#define HAMG 0x0400
|
||||
#define HAMR 0x0200
|
||||
#define HAMC 0x1000
|
||||
#define HAMFREE 0x2000
|
||||
|
||||
static void addhamdither(short x, unsigned char *dit,
|
||||
short dmax, unsigned char *rgb,
|
||||
unsigned short *ham,
|
||||
short type, short round, short shift)
|
||||
/* short x, dmax, type, round, shift; */
|
||||
/* uchar *dit, *rgb; */
|
||||
/* unsigned short *ham; */
|
||||
{
|
||||
short dx = 0;
|
||||
short c1, c2;
|
||||
|
||||
for (;x>0;x--){
|
||||
if (ham[0] & (HAMFREE | type)){
|
||||
c2 = c1 = *rgb;
|
||||
|
||||
/* wrap dither */
|
||||
while (dx >= dmax) dx -= dmax;
|
||||
|
||||
c1 += dit[dx];
|
||||
if (c1 > 255) c1 = 255;
|
||||
c2 += round;
|
||||
if (c2 > 255) c2 = 255;
|
||||
|
||||
if (c1 != c2){
|
||||
c1 >>= shift; c2 >>= shift;
|
||||
if (ham[1] & HAMFREE){
|
||||
ham[0] = type + c1;
|
||||
ham[1] = type + c2;
|
||||
} else if (ham[1] & type){
|
||||
ham[0] = type + c1;
|
||||
} else if ((ham[2] & (type | HAMFREE)) == type){
|
||||
ham[0] = type + c1;
|
||||
} else if ((ham[1] & HAMC) | (ham[2] & HAMC)){
|
||||
ham[0] = type + c1;
|
||||
}
|
||||
}
|
||||
}
|
||||
rgb += 4;
|
||||
ham ++;
|
||||
dx ++;
|
||||
}
|
||||
}
|
||||
|
||||
static void convhamscanl(short x, short y,
|
||||
unsigned char *rgbbase,
|
||||
unsigned char coltab[][4],
|
||||
short *deltab,
|
||||
short bits)
|
||||
/* short x, y, bits; */
|
||||
/* uchar *rgbbase; */
|
||||
/* uchar coltab[][4]; */
|
||||
/* short *deltab; */
|
||||
{
|
||||
int a, r, g, b, lr, lg, lb, dr, dg, db, col, fout, type, x2;
|
||||
int round, shift;
|
||||
uchar *rgb, dit[2];
|
||||
unsigned short *ham, *hambase;
|
||||
|
||||
/* Opzet:
|
||||
eerst wordt het gehele plaatje afgelopen, waarbij kleurovergangen gecodeerd
|
||||
worden: FGRB XXXX XXXX
|
||||
F - vrije kleurwaarde, mag door ieder veranderd worden
|
||||
G/R/B - groen/rood/blauw ham overgang, alleen door die kleur te veranderen
|
||||
XXXX XXXX - N bits waarde.
|
||||
|
||||
0000 XXXX XXXX is palet kleur.
|
||||
|
||||
daarna wordt eerst de groen dither toegevoegd, dan de rood dither en
|
||||
tenslotte wordt blauwdither toegevoegd
|
||||
*/
|
||||
|
||||
if ((hambase = (unsigned short *) malloc((x+4) * sizeof(unsigned short)))==0) return;
|
||||
|
||||
lb = coltab[0][1];
|
||||
lg = coltab[0][2];
|
||||
lr = coltab[0][3];
|
||||
type = col = 0;
|
||||
|
||||
ham = hambase;
|
||||
rgb = rgbbase;
|
||||
|
||||
shift = 8 - bits;
|
||||
round = 1 << (shift - 1);
|
||||
|
||||
/* om te voorkomen dat er 'ruis' ontstaat aan het einde van de regel */
|
||||
for (x2 = 3; x2 >= 0; x2 --) hambase[x + x2] = HAMFREE;
|
||||
|
||||
for (x2 = x ;x2 > 0; x2--){
|
||||
r = rgb[0] + round;
|
||||
g = rgb[1] + round;
|
||||
b = rgb[2] + round;
|
||||
a = rgb[3];
|
||||
|
||||
if (a < 128 && alpha_col0) {
|
||||
a = 1;
|
||||
} else a = 0;
|
||||
|
||||
if (b > 255) b = 255;
|
||||
if (g > 255) {
|
||||
g = 255;
|
||||
}
|
||||
if (r > 255) r = 255;
|
||||
|
||||
r >>= shift;
|
||||
g >>= shift;
|
||||
b >>= shift;
|
||||
|
||||
if ((b-lb) | (g-lg) | (r-lr) | a){
|
||||
if (a) {
|
||||
col = 0;
|
||||
type = HAMC;
|
||||
} else {
|
||||
col = ((b << (2 * bits)) + (g << bits) + r) << 1;
|
||||
fout = deltab[col + 1];
|
||||
col = deltab[col];
|
||||
type = HAMC;
|
||||
|
||||
dr = quadr[lr-r];
|
||||
dg = quadr[lg-g];
|
||||
db = quadr[lb-b];
|
||||
|
||||
if ((dr+dg) <= fout){
|
||||
fout = dr+dg;
|
||||
col = b;
|
||||
type = HAMB;
|
||||
}
|
||||
if ((dg+db) <= fout){
|
||||
fout = dg+db;
|
||||
col = r;
|
||||
type = HAMR;
|
||||
}
|
||||
if ((dr+db) <= fout){
|
||||
fout = dr+db;
|
||||
col = g;
|
||||
type = HAMG;
|
||||
}
|
||||
}
|
||||
|
||||
switch(type){
|
||||
case HAMG:
|
||||
lg = g;
|
||||
break;
|
||||
case HAMR:
|
||||
lr = r;
|
||||
break;
|
||||
case HAMB:
|
||||
lb = b;
|
||||
break;
|
||||
default:
|
||||
lb = coltab[col][1];
|
||||
lg = coltab[col][2];
|
||||
lr = coltab[col][3];
|
||||
}
|
||||
*ham = type + col;
|
||||
} else *ham = HAMG + HAMFREE + g;
|
||||
|
||||
rgb += 4;
|
||||
ham ++;
|
||||
}
|
||||
|
||||
|
||||
if (y & 1){
|
||||
dit[0] = 0 << (shift - 2);
|
||||
dit[1] = 3 << (shift - 2);
|
||||
} else {
|
||||
dit[0] = 2 << (shift - 2);
|
||||
dit[1] = 1 << (shift - 2);
|
||||
}
|
||||
|
||||
addhamdither(x,dit,2,rgbbase+2,hambase,HAMG, round, shift);
|
||||
|
||||
if ((y & 1)==0){
|
||||
dit[0] = 3 << (shift - 2);
|
||||
dit[1] = 0 << (shift - 2);
|
||||
} else {
|
||||
dit[0] = 1 << (shift - 2);
|
||||
dit[1] = 2 << (shift - 2);
|
||||
}
|
||||
|
||||
addhamdither(x,dit,2,rgbbase+3,hambase,HAMR, round, shift);
|
||||
addhamdither(x,dit,2,rgbbase+1,hambase,HAMB, round, shift);
|
||||
|
||||
|
||||
ham = hambase;
|
||||
rgb = rgbbase;
|
||||
rgb += 3;
|
||||
|
||||
for (x2=x;x2>0;x2--){
|
||||
type = *(ham++);
|
||||
if (type & HAMG) type |= HAMR | HAMB;
|
||||
|
||||
*rgb = (type & 0xff) | ((type & (HAMR | HAMB)) >> shift);
|
||||
rgb += 4;
|
||||
}
|
||||
|
||||
free (hambase);
|
||||
}
|
||||
|
||||
|
||||
short imb_converttoham(struct ImBuf *ibuf)
|
||||
/* struct ImBuf* ibuf; */
|
||||
{
|
||||
unsigned int coltab[256],*rect;
|
||||
short x,y,* deltab;
|
||||
int mincol;
|
||||
|
||||
memcpy(coltab,ibuf->cmap,4 * ibuf->maxcol);
|
||||
|
||||
mincol = ibuf->mincol;
|
||||
if (alpha_col0 && mincol == 0) mincol = 1;
|
||||
|
||||
if (ibuf->ftype == AN_hamx) {
|
||||
deltab = imb_coldeltatab((uchar *) coltab, 0, ibuf->maxcol, 4);
|
||||
} else {
|
||||
ibuf->cbits = ibuf->depth - 2;
|
||||
imb_losecmapbits(ibuf, coltab);
|
||||
deltab = imb_coldeltatab((uchar *) coltab, mincol, ibuf->maxcol, ibuf->cbits);
|
||||
}
|
||||
|
||||
rect = ibuf->rect;
|
||||
x=ibuf->x;
|
||||
y=ibuf->y;
|
||||
|
||||
if (ibuf->ftype == AN_hamx){
|
||||
IMB_dit2(ibuf, 2, 4);
|
||||
IMB_dit2(ibuf, 1, 4);
|
||||
IMB_dit2(ibuf, 0, 4);
|
||||
imb_convhamx(ibuf, coltab, deltab);
|
||||
} else {
|
||||
for(;y > 0; y--){
|
||||
convhamscanl(x, y, rect, coltab, deltab, ibuf->cbits);
|
||||
rect += x;
|
||||
}
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
Reference in New Issue
Block a user