...
|
...
|
@@ -13,13 +13,14 @@
|
13
|
13
|
#include <stdlib.h>
|
14
|
14
|
#include <unistd.h>
|
15
|
15
|
#include <string.h>
|
|
16
|
+#include <math.h>
|
16
|
17
|
#include <png.h>
|
17
|
18
|
|
18
|
19
|
#define DEFAULT_IDENTITYSIZE 12 /* Same as RawTherapee's HaldCLUTs, 1728x1728 AKA (12*12)*12x12*(12*12), equivalent to a cube with 144px wide sides*/
|
19
|
20
|
#define DEFAULT_QUALITY 85
|
20
|
21
|
/* #define JPEG_SUPPORTED */
|
21
|
22
|
|
22
|
|
-int luttool_applylut(char *lutfilenamelist,char *infilename, char *outfilename,int quality,int identitysize);
|
|
23
|
+int luttool_applylut(char *lutfilenamelist,char *infilename, char *outfilename,int quality,int identitysize,int flaginterpolatelut);
|
23
|
24
|
|
24
|
25
|
int util_pnginfo(char *filename, int *width, int *height);
|
25
|
26
|
int util_pngload(char *filename, char **bufimg, int *sizebufimg, int *width, int *height);
|
...
|
...
|
@@ -39,25 +40,36 @@ main(int argc, char *argv[])
|
39
|
40
|
char *lutlist;
|
40
|
41
|
int i;
|
41
|
42
|
int flagseveralinfile;
|
|
43
|
+ int flaginterpolatelut;
|
42
|
44
|
char bufoutfilename[1024];
|
43
|
45
|
char *currentoutfilename;
|
44
|
46
|
if(argc<2 || strcmp(argv[argc-1],"--help")==0) {
|
45
|
47
|
#ifdef JPEG_SUPPORTED
|
46
|
|
- printf("Syntax: %s [-q jpegquality] [-n identitylevel] {identity | lutfile[,lutfile[,...]]} { identity | infile1 } [infile2 [...]] -o outfile\n",argv[0]);
|
|
48
|
+ printf("Syntax: %s [-i] [-q jpegquality] [-n identitylevel] {identity | lutfile[,lutfile[,...]]} { identity | infile1 } [infile2 [...]] -o outfile\n",argv[0]);
|
47
|
49
|
printf("Example: %s haldclut.png sprite.png -o result.png\n",argv[0]);
|
|
50
|
+ printf("Example: %s -i haldclut.png sprite.png -o result.png\n",argv[0]);
|
48
|
51
|
printf("Example: %s -n 16 identity identity -o identity.png\n",argv[0]);
|
49
|
52
|
printf("Example: %s -q 85 haldclut.png infile.png -o outfile.jpg\n",argv[0]);
|
|
53
|
+ printf("NOTE: -i makes the program interpolate the LUTs.\n");
|
50
|
54
|
#else
|
51
|
55
|
printf("Syntax: %s [-n identitylevel] {identity | lutfile[,lutfile[,...]]} { identity | infile1 } [infile2 [...]] -o outfile\n",argv[0]);
|
52
|
56
|
printf("Example: %s haldclut.png sprite.png -o result.png\n",argv[0]);
|
|
57
|
+ printf("Example: -i %s haldclut.png sprite.png -o result.png\n",argv[0]);
|
53
|
58
|
printf("Example: %s -n 16 identity identity -o identity.png\n",argv[0]);
|
|
59
|
+ printf("NOTE: -i makes the program interpolate the LUTs.\n");
|
54
|
60
|
#endif
|
55
|
61
|
return(1);
|
56
|
62
|
}
|
57
|
63
|
/* parse arguments */
|
58
|
64
|
identitysize=DEFAULT_IDENTITYSIZE;
|
59
|
65
|
quality=DEFAULT_QUALITY;
|
60
|
|
- for(firstarg=1;firstarg<(argc-1) && (strcmp(argv[firstarg],"-n")==0 || (strcmp(argv[firstarg],"-q")==0));) {
|
|
66
|
+ flaginterpolatelut=0;
|
|
67
|
+ for(firstarg=1
|
|
68
|
+ ;firstarg<(argc-1)
|
|
69
|
+ && (strcmp(argv[firstarg],"-n")==0
|
|
70
|
+ || strcmp(argv[firstarg],"-q")==0
|
|
71
|
+ || strcmp(argv[firstarg],"-i")==0)
|
|
72
|
+ ;) {
|
61
|
73
|
if(strcmp(argv[firstarg],"-n")==0) {
|
62
|
74
|
identitysize=atoi(argv[firstarg+1]);
|
63
|
75
|
if(identitysize<2 || identitysize>16) {
|
...
|
...
|
@@ -70,6 +82,9 @@ main(int argc, char *argv[])
|
70
|
82
|
fprintf(stderr,"%s: ERROR: the parameter to -q must be between 1 and 100 (default: %i)\n",argv[0],DEFAULT_QUALITY);
|
71
|
83
|
return(1);
|
72
|
84
|
}
|
|
85
|
+ } else if(strcmp(argv[firstarg],"-i")==0) {
|
|
86
|
+ flaginterpolatelut=1;
|
|
87
|
+ firstarg--; /* doesn't have param. */
|
73
|
88
|
}
|
74
|
89
|
firstarg+=2;
|
75
|
90
|
}
|
...
|
...
|
@@ -107,7 +122,7 @@ main(int argc, char *argv[])
|
107
|
122
|
bufoutfilename[sizeof(bufoutfilename)-1]='\0';
|
108
|
123
|
currentoutfilename=bufoutfilename;
|
109
|
124
|
}
|
110
|
|
- if(luttool_applylut(lutlist,argv[i],currentoutfilename,quality,identitysize)!=0) {
|
|
125
|
+ if(luttool_applylut(lutlist,argv[i],currentoutfilename,quality,identitysize,flaginterpolatelut)!=0) {
|
111
|
126
|
fprintf(stderr,"%s: ERROR: couldn't apply LUTs \"%s\" to \"%s\" or couldn't write \"%s\"\n",argv[0],lutlist,argv[i],currentoutfilename);
|
112
|
127
|
return(1);
|
113
|
128
|
}
|
...
|
...
|
@@ -116,7 +131,7 @@ main(int argc, char *argv[])
|
116
|
131
|
}
|
117
|
132
|
|
118
|
133
|
int
|
119
|
|
-luttool_applylut(char *lutlist,char *infilename, char *outfilename,int quality,int identitysize)
|
|
134
|
+luttool_applylut(char *lutlist,char *infilename, char *outfilename,int quality,int identitysize,int flaginterpolatelut)
|
120
|
135
|
{
|
121
|
136
|
char *curlut,*next;
|
122
|
137
|
char filename[1024];
|
...
|
...
|
@@ -126,6 +141,7 @@ luttool_applylut(char *lutlist,char *infilename, char *outfilename,int quality,i
|
126
|
141
|
int sizelutbuf,lutwidth,lutheight;
|
127
|
142
|
int sizeimgbuf,imgwidth,imgheight;
|
128
|
143
|
int sizergblutbuf;
|
|
144
|
+ int res;
|
129
|
145
|
lutbuf=imgbuf=rgblutbuf=NULL;
|
130
|
146
|
sizelutbuf=sizeimgbuf=sizergblutbuf=0;
|
131
|
147
|
lutwidth=lutheight=imgwidth=imgheight=0;
|
...
|
...
|
@@ -159,7 +175,12 @@ luttool_applylut(char *lutlist,char *infilename, char *outfilename,int quality,i
|
159
|
175
|
break; /* couldn't load lut */
|
160
|
176
|
}
|
161
|
177
|
}
|
162
|
|
- if(luttool_rgba2lut4096(lutbuf, lutwidth, lutheight, &rgblutbuf, &sizergblutbuf)!=0) {
|
|
178
|
+ res=0;
|
|
179
|
+ if(flaginterpolatelut==0)
|
|
180
|
+ res=luttool_rgba2lut4096(lutbuf, lutwidth, lutheight, &rgblutbuf, &sizergblutbuf);
|
|
181
|
+ else
|
|
182
|
+ res=luttool_rgba2lut4096_interpolated(lutbuf, lutwidth, lutheight, &rgblutbuf, &sizergblutbuf);
|
|
183
|
+ if(res!=0) {
|
163
|
184
|
in_error=1;
|
164
|
185
|
break; /* couldn't process lut */
|
165
|
186
|
}
|
...
|
...
|
@@ -387,6 +408,92 @@ luttool_rgba2lut4096(char *rgba, int width, int height, char **lut4096, int *siz
|
387
|
408
|
return(0);
|
388
|
409
|
}
|
389
|
410
|
|
|
411
|
+int
|
|
412
|
+luttool_rgba2lut4096_interpolated(char *rgba, int width, int height, char **lut4096, int *sizelut4096)
|
|
413
|
+{
|
|
414
|
+ int n;
|
|
415
|
+ int reqsize;
|
|
416
|
+ float fr,fg,fb;
|
|
417
|
+ int ir,ig,ib;
|
|
418
|
+ int incr,incg,incb;
|
|
419
|
+ int posr,posg,posb;
|
|
420
|
+ int myrgb[3];
|
|
421
|
+ int x,y;
|
|
422
|
+ int r,g,b;
|
|
423
|
+ int i;
|
|
424
|
+ int isize,isizesq,isizesqminusone;
|
|
425
|
+ int osize,osizesq,osizesqminusone;
|
|
426
|
+ unsigned char *orig,*dest;
|
|
427
|
+ if(rgba==NULL || width!=height || lut4096==NULL || sizelut4096==NULL)
|
|
428
|
+ return(-1); /* sanity check error */
|
|
429
|
+ /* check if size is a supported size */
|
|
430
|
+ for(n=2;n<=16 && width!=(n*n*n);n++)
|
|
431
|
+ ;
|
|
432
|
+ if(n>16)
|
|
433
|
+ return(-1); /* invalid size */
|
|
434
|
+ /* expand lut4096 as necessary */
|
|
435
|
+ reqsize=4096*4096*3;
|
|
436
|
+ if(*sizelut4096<reqsize) {
|
|
437
|
+ char *newlut4096;
|
|
438
|
+ if((newlut4096=realloc(*lut4096,reqsize))==NULL)
|
|
439
|
+ return(-1); /* insuf. mem. for resulting lut */
|
|
440
|
+ *lut4096=newlut4096;
|
|
441
|
+ *sizelut4096=reqsize;
|
|
442
|
+ }
|
|
443
|
+ /* do the conversion */
|
|
444
|
+ isize=n;
|
|
445
|
+ isizesq=n*n;
|
|
446
|
+ isizesqminusone=isizesq-1;
|
|
447
|
+ osize=16;
|
|
448
|
+ osizesq=osize*osize;
|
|
449
|
+ osizesqminusone=osizesq-1;
|
|
450
|
+ for(r=0;r<osizesq;r++) {
|
|
451
|
+ for(g=0;g<osizesq;g++) {
|
|
452
|
+ for(b=0;b<osizesq;b++) {
|
|
453
|
+ fr=((isizesqminusone*((float)r))/osizesqminusone);
|
|
454
|
+ fg=((isizesqminusone*((float)g))/osizesqminusone);
|
|
455
|
+ fb=((isizesqminusone*((float)b))/osizesqminusone);
|
|
456
|
+ ir=floorf(fr);
|
|
457
|
+ ig=floorf(fg);
|
|
458
|
+ ib=floorf(fb);
|
|
459
|
+ fr=fr-ir;
|
|
460
|
+ fg=fg-ig;
|
|
461
|
+ fb=fb-ib;
|
|
462
|
+ myrgb[0]=myrgb[1]=myrgb[2]=0;
|
|
463
|
+ for(i=0;i<2*2*2;i++) {
|
|
464
|
+ incr=(i>>2)&1;
|
|
465
|
+ incg=(i>>1)&1;
|
|
466
|
+ incb=i&1;
|
|
467
|
+ posr=ir+incr;
|
|
468
|
+ posr=(posr<0)?0:(posr>=isizesq)?isizesqminusone:posr;
|
|
469
|
+ posg=ig+incg;
|
|
470
|
+ posg=(posg<0)?0:(posg>=isizesq)?isizesqminusone:posg;
|
|
471
|
+ posb=ib+incb;
|
|
472
|
+ posb=(posb<0)?0:(posb>=isizesq)?isizesqminusone:posb;
|
|
473
|
+ x=posr+(posg%isize)*isizesq;
|
|
474
|
+ y=posb*isize+(posg/isize);
|
|
475
|
+ orig=(unsigned char *) (rgba+((y*width+x)<<2));
|
|
476
|
+ myrgb[0]+=orig[0]*((incr!=0)?fr:(1-fr));
|
|
477
|
+ myrgb[1]+=orig[1]*((incg!=0)?fg:(1-fg));
|
|
478
|
+ myrgb[2]+=orig[2]*((incb!=0)?fb:(1-fb));
|
|
479
|
+ }
|
|
480
|
+ myrgb[0]/=(i/2);
|
|
481
|
+ myrgb[0]=(myrgb[0]<0)?0:(myrgb[0]>255)?255:myrgb[0];
|
|
482
|
+ myrgb[1]/=(i/2);
|
|
483
|
+ myrgb[1]=(myrgb[1]<0)?0:(myrgb[1]>255)?255:myrgb[1];
|
|
484
|
+ myrgb[2]/=(i/2);
|
|
485
|
+ myrgb[2]=(myrgb[2]<0)?0:(myrgb[2]>255)?255:myrgb[2];
|
|
486
|
+ dest=(unsigned char *) ((*lut4096)+((r<<16)+(g<<8)+b)*3);
|
|
487
|
+ dest[0]=myrgb[0];
|
|
488
|
+ dest[1]=myrgb[1];
|
|
489
|
+ dest[2]=myrgb[2];
|
|
490
|
+ }
|
|
491
|
+ }
|
|
492
|
+ }
|
|
493
|
+ return(0);
|
|
494
|
+}
|
|
495
|
+
|
|
496
|
+
|
390
|
497
|
int
|
391
|
498
|
luttool_applylut4096(char *lut4096,char *imgbuf,int imgwidth,int imgheight)
|
392
|
499
|
{
|