Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/cmd/jpg/totruecolor.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <draw.h>
5
#include "imagefile.h"
6
 
7
enum {
8
	c1 = 2871,	/* 1.402 * 2048 */
9
	c2 = 705,		/* 0.34414 * 2048 */
10
	c3 = 1463,	/* 0.71414 * 2048 */
11
	c4 = 3629,	/* 1.772 * 2048 */
12
};
13
 
14
Rawimage*
15
totruecolor(Rawimage *i, int chandesc)
16
{
17
	int j, k;
18
	Rawimage *im;
19
	char err[ERRMAX];
20
	uchar *rp, *gp, *bp, *cmap, *inp, *outp, cmap1[3*256];
21
	int r, g, b, Y, Cr, Cb;
22
 
23
	if(chandesc!=CY && chandesc!=CRGB24)
24
		return _remaperror("remap: can't convert to chandesc %d", chandesc);
25
 
26
	err[0] = '\0';
27
	errstr(err, sizeof err);	/* throw it away */
28
	im = malloc(sizeof(Rawimage));
29
	if(im == nil)
30
		return nil;
31
	memset(im, 0, sizeof(Rawimage));
32
	if(chandesc == CY)
33
		im->chanlen = i->chanlen;
34
	else
35
		im->chanlen = 3*i->chanlen;
36
	im->chandesc = chandesc;
37
	im->chans[0] = malloc(im->chanlen);
38
	if(im->chans[0] == nil){
39
		free(im);
40
		return nil;
41
	}
42
	im->r = i->r;
43
	im->nchans = 1;
44
 
45
	cmap = i->cmap;
46
 
47
	outp = im->chans[0];
48
 
49
	switch(i->chandesc){
50
	default:
51
		return _remaperror("remap: can't recognize channel type %d", i->chandesc);
52
	case CY:
53
		if(i->nchans != 1)
54
			return _remaperror("remap: Y image has %d chans", i->nchans);
55
		if(chandesc == CY){
56
			memmove(im->chans[0], i->chans[0], i->chanlen);
57
			break;
58
		}
59
		/* convert to three color */
60
		inp = i->chans[0];
61
		for(j=0; j<i->chanlen; j++){
62
			k = *inp++;
63
			*outp++ = k;
64
			*outp++ = k;
65
			*outp++ = k;
66
		}
67
		break;
68
 
69
	case CRGB1:
70
		if(cmap == nil)
71
			return _remaperror("remap: image has no color map");
72
		if(i->nchans != 1)
73
			return _remaperror("remap: can't handle nchans %d", i->nchans);
74
		for(j=1; j<=8; j++)
75
			if(i->cmaplen == 3*(1<<j))
76
				break;
77
		if(j > 8)
78
			return _remaperror("remap: can't do colormap size 3*%d", i->cmaplen/3);
79
		if(i->cmaplen != 3*256){
80
			/* to avoid a range check in loop below, make a full-size cmap */
81
			memmove(cmap1, cmap, i->cmaplen);
82
			cmap = cmap1;
83
		}
84
		inp = i->chans[0];
85
		if(chandesc == CY){
86
			for(j=0; j<i->chanlen; j++){
87
				k = *inp++;
88
				r = cmap[3*k+2];
89
				g = cmap[3*k+1];
90
				b = cmap[3*k+0];
91
				r = (2125*r + 7154*g + 721*b)/10000;	/* Poynton page 84 */
92
				*outp++ = r;
93
			}
94
		}else{
95
			for(j=0; j<i->chanlen; j++){
96
				k = *inp++;
97
				*outp++ = cmap[3*k+2];
98
				*outp++ = cmap[3*k+1];
99
				*outp++ = cmap[3*k+0];
100
			}
101
		}
102
		break;
103
 
104
	case CRGB:
105
		if(i->nchans != 3)
106
			return _remaperror("remap: can't handle nchans %d", i->nchans);
107
		rp = i->chans[0];
108
		gp = i->chans[1];
109
		bp = i->chans[2];
110
		if(chandesc == CY){
111
			for(j=0; j<i->chanlen; j++){
112
				r = *bp++;
113
				g = *gp++;
114
				b = *rp++;
115
				r = (2125*r + 7154*g + 721*b)/10000;	/* Poynton page 84 */
116
				*outp++ = r;
117
			}
118
		}else
119
			for(j=0; j<i->chanlen; j++){
120
				*outp++ = *bp++;
121
				*outp++ = *gp++;
122
				*outp++ = *rp++;
123
			}
124
		break;
125
 
126
	case CYCbCr:
127
		if(i->nchans != 3)
128
			return _remaperror("remap: can't handle nchans %d", i->nchans);
129
		rp = i->chans[0];
130
		gp = i->chans[1];
131
		bp = i->chans[2];
132
		for(j=0; j<i->chanlen; j++){
133
			Y = *rp++ << 11;
134
			Cb = *gp++ - 128;
135
			Cr = *bp++ - 128;
136
			r = (Y+c1*Cr) >> 11;
137
			g = (Y-c2*Cb-c3*Cr) >> 11;
138
			b = (Y+c4*Cb) >> 11;
139
			if(r < 0)
140
				r = 0;
141
			if(r > 255)
142
				r = 255;
143
			if(g < 0)
144
				g = 0;
145
			if(g > 255)
146
				g = 255;
147
			if(b < 0)
148
				b = 0;
149
			if(b > 255)
150
				b = 255;
151
			if(chandesc == CY){
152
				r = (2125*r + 7154*g + 721*b)/10000;
153
				*outp++ = r;
154
			}else{
155
				*outp++ = b;
156
				*outp++ = g;
157
				*outp++ = r;
158
			}
159
		}
160
		break;
161
	}
162
	return im;
163
}