diff options
author | Lars-Dominik Braun <lars@6xq.net> | 2015-02-15 19:36:02 +0100 |
---|---|---|
committer | Lars-Dominik Braun <lars@6xq.net> | 2015-05-02 21:36:45 +0200 |
commit | 716eacfc7c2301fa20fdc71d473d4def8f790adb (patch) | |
tree | 847ebbf78f963d0bfb19af65ce84f34d0eac5279 | |
parent | de0a8d8ff492fe1ede5ae2b3bad3d3bf659934d1 (diff) | |
download | pucket-716eacfc7c2301fa20fdc71d473d4def8f790adb.tar.gz pucket-716eacfc7c2301fa20fdc71d473d4def8f790adb.tar.bz2 pucket-716eacfc7c2301fa20fdc71d473d4def8f790adb.zip |
Use floating point color values in [0,1]
Internal color representation is [0,1] now for every channel.
-rw-r--r-- | palettes.c | 30 | ||||
-rw-r--r-- | palettes.h | 2 | ||||
-rw-r--r-- | private.h | 1 | ||||
-rw-r--r-- | rect.c | 44 |
4 files changed, 37 insertions, 40 deletions
@@ -58,9 +58,9 @@ static void parse_palettes(xmlNode *node) { while (isspace( (int)val[c_idx])) c_idx++; - pal->colors[col_count][0] = r; - pal->colors[col_count][1] = g; - pal->colors[col_count][2] = b; + pal->colors[col_count][0] = (double)r/255.0; + pal->colors[col_count][1] = (double)g/255.0; + pal->colors[col_count][2] = (double)b/255.0; col_count++; } while (col_count<count); @@ -169,9 +169,9 @@ int flam3_get_palette(int n, flam3_palette c, double hue_rotation, randctx * con double4 rgb, hsv; rgb = (double4) { - the_palettes[idx].colors[ii][0] / 255.0, - the_palettes[idx].colors[ii][1] / 255.0, - the_palettes[idx].colors[ii][2] / 255.0, + the_palettes[idx].colors[ii][0], + the_palettes[idx].colors[ii][1], + the_palettes[idx].colors[ii][2], 1.0, }; @@ -296,39 +296,39 @@ double4 flam3_calc_newrgb(double4 cbuf, double ls, double highpow) { /* Identify the most saturated channel */ for (rgbi=0;rgbi<3;rgbi++) { - a = ls * (cbuf[rgbi]/PREFILTER_WHITE); + a = ls * (cbuf[rgbi]); if (a>maxa) { maxa = a; - maxc = cbuf[rgbi]/PREFILTER_WHITE; + maxc = cbuf[rgbi]; } } /* If a channel is saturated and we have a non-negative highlight power */ /* modify the color to prevent hue shift */ - if (maxa>255 && highpow>=0.0) { - newls = 255.0/maxc; + if (maxa > 1.0 && highpow>=0.0) { + newls = 1.0/maxc; lsratio = pow(newls/ls,highpow); /* Calculate the max-value color (ranged 0 - 1) */ - double4 newrgb = newls*(cbuf/PREFILTER_WHITE)/255.0; + double4 newrgb = newls*(cbuf); /* Reduce saturation by the lsratio */ double4 newhsv = rgb2hsv(newrgb); newhsv[1] *= lsratio; - return hsv2rgb(newhsv) * 255.0; + return hsv2rgb(newhsv); } else { - newls = 255.0/maxc; + newls = 1.0/maxc; adjhlp = -highpow; if (adjhlp>1) adjhlp=1; - if (maxa<=255) + if (maxa<=1.0) adjhlp=1.0; /* Calculate the max-value color (ranged 0 - 1) interpolated with the old * behaviour */ - return ((1.0-adjhlp)*newls + adjhlp*ls)*(cbuf/PREFILTER_WHITE); + return ((1.0-adjhlp)*newls + adjhlp*ls)*(cbuf); } } @@ -23,7 +23,7 @@ typedef struct { int number; char name[flam3_name_len]; - unsigned char colors[256][3]; + double colors[256][3]; } lib_palette; #include "vector.h" @@ -35,7 +35,6 @@ #include <pthread.h> -#define PREFILTER_WHITE 255 #define EPS (1e-10) #define CMAP_SIZE 256 #define CMAP_SIZE_M1 255 @@ -40,7 +40,6 @@ /* allow this many iterations for settling into attractor */ #define FUSE_27 15 #define FUSE_28 100 -#define WHITE_LEVEL 255 static void iter_thread(void *fth) { double sub_batch; @@ -444,7 +443,7 @@ int render_rectangle(flam3_frame *spec, void *out, for (j = 0; j < CMAP_SIZE; j++) { dmap[j].index = cp.palette[(j * 256) / CMAP_SIZE].index / 256.0; for (k = 0; k < 4; k++) - dmap[j].color[k] = (cp.palette[(j * 256) / CMAP_SIZE].color[k] * WHITE_LEVEL) * color_scalar; + dmap[j].color[k] = cp.palette[(j * 256) / CMAP_SIZE].color[k] * color_scalar; } /* compute camera */ @@ -583,11 +582,11 @@ int render_rectangle(flam3_frame *spec, void *out, } - k1 =(cp.contrast * cp.brightness * - PREFILTER_WHITE * 268.0 * batch_filter[batch_num]) / 256; + /* XXX: the original formula has a factor 268/256 in here, not sure why */ + k1 = cp.contrast * cp.brightness * batch_filter[batch_num]; area = image_width * image_height / (ppux * ppuy); k2 = (oversample * oversample * nbatches) / - (cp.contrast * area * WHITE_LEVEL * sample_density * sumfilt); + (cp.contrast * area * sample_density * sumfilt); #if 0 printf("iw=%d,ih=%d,ppux=%f,ppuy=%f\n",image_width,image_height,ppux,ppuy); printf("contrast=%f, brightness=%f, PREFILTER=%d, temporal_filter=%f\n", @@ -630,9 +629,9 @@ int render_rectangle(flam3_frame *spec, void *out, double linrange = cp.gam_lin_thresh; vibrancy /= vib_gam_n; - background[0] /= vib_gam_n/256.0; - background[1] /= vib_gam_n/256.0; - background[2] /= vib_gam_n/256.0; + background[0] /= vib_gam_n; + background[1] /= vib_gam_n; + background[2] /= vib_gam_n; /* If we're in the early clip mode, perform this first step to */ /* apply the gamma correction and clipping before the spat filt */ @@ -647,9 +646,9 @@ int render_rectangle(flam3_frame *spec, void *out, alpha = 0.0; ls = 0.0; } else { - tmp=ac[3]/PREFILTER_WHITE; + tmp=ac[3]; alpha = flam3_calc_alpha(tmp,g,linrange); - ls = vibrancy * 256.0 * alpha / tmp; + ls = vibrancy * alpha / tmp; if (alpha<0.0) alpha = 0.0; if (alpha>1.0) alpha = 1.0; } @@ -660,7 +659,7 @@ int render_rectangle(flam3_frame *spec, void *out, for (rgbi=0;rgbi<3;rgbi++) { a = newrgb[rgbi]; - a += (1.0-vibrancy) * 256.0 * pow( t[rgbi] / PREFILTER_WHITE, g); + a += (1.0-vibrancy) * pow( t[rgbi], g); if (nchan<=3 || transp==0) a += ((1.0 - alpha) * background[rgbi]); else { @@ -671,7 +670,7 @@ int render_rectangle(flam3_frame *spec, void *out, } /* Clamp here to ensure proper filter functionality */ - if (a>255) a = 255; + if (a>1.0) a = 1.0; if (a<0) a = 0; /* Replace values in accumulation buffer with these new ones */ @@ -718,14 +717,14 @@ int render_rectangle(flam3_frame *spec, void *out, /* The old way, spatial filter first and then clip after gamma */ if (!spec->earlyclip) { - tmp=t[3]/PREFILTER_WHITE; + tmp=t[3]; if (t[3]<=0) { alpha = 0.0; ls = 0.0; } else { alpha = flam3_calc_alpha(tmp,g,linrange); - ls = vibrancy * 256.0 * alpha / tmp; + ls = vibrancy * alpha / tmp; if (alpha<0.0) alpha = 0.0; if (alpha>1.0) alpha = 1.0; } @@ -734,7 +733,7 @@ int render_rectangle(flam3_frame *spec, void *out, for (rgbi=0;rgbi<3;rgbi++) { a = newrgb[rgbi]; - a += (1.0-vibrancy) * 256.0 * pow( t[rgbi] / PREFILTER_WHITE, g); + a += (1.0-vibrancy) * pow( t[rgbi], g); if (nchan<=3 || transp==0) a += ((1.0 - alpha) * background[rgbi]); else { @@ -745,7 +744,7 @@ int render_rectangle(flam3_frame *spec, void *out, } /* Clamp here to ensure proper filter functionality */ - if (a>255) a = 255; + if (a>1.0) a = 1.0; if (a<0) a = 0; /* Replace values in accumulation buffer with these new ones */ @@ -758,16 +757,15 @@ int render_rectangle(flam3_frame *spec, void *out, a = t[rgbi]; - if (a > 255) - a = 255; + if (a > 1.0) + a = 1.0; if (a < 0) a = 0; if (2==bytes_per_channel) { - a *= 256.0; /* Scales to [0-65280] */ - p16[rgbi] = (unsigned short) a; + p16[rgbi] = nearbyint (a * 65535.0); } else { - p8[rgbi] = (unsigned char) a; + p8[rgbi] = nearbyint (a * 255.0); } } @@ -781,9 +779,9 @@ int render_rectangle(flam3_frame *spec, void *out, if (nchan>3) { if (transp==1) { if (2==bytes_per_channel) - p16[3] = (unsigned short) (t[3] * 65535); + p16[3] = nearbyint (t[3] * 65535.0); else - p8[3] = (unsigned char) (t[3] * 255); + p8[3] = nearbyint (t[3] * 255); } else { if (2==bytes_per_channel) p16[3] = 65535; |