diff --git a/README.md b/README.md index c035604..bb4ef80 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ Apply a falsecolor palette -m Path to WXtoImg map -p Path to palette -r Realtime decode +-g Gamma adjustment (1.0 = off) ``` ### Image types diff --git a/common.h b/common.h index 7dc01f0..e994fcc 100644 --- a/common.h +++ b/common.h @@ -46,6 +46,7 @@ typedef struct { int realtime; // Realtime decoding char *filename; // Output filename char *palette; // Filename of palette + float gamma; // Gamma } options_t; enum imagetypes { diff --git a/image.c b/image.c index 4bdff4f..6eb4bff 100644 --- a/image.c +++ b/image.c @@ -241,7 +241,7 @@ int calibrate(float **prow, int nrow, int offset, int width) { } -void distrib(options_t *opts, image_t *img, char *chid) { +void distrib(options_t *opts, image_t *img, char chid) { int max = 0; // Options @@ -276,7 +276,7 @@ void distrib(options_t *opts, image_t *img, char *chid) { for(int y = 0; y < 256; y++) distrib.prow[y][x] = distrib.prow[y][x] / max * 255.0; - extern int ImageOut(options_t *opts, image_t *img, int offset, int width, char *desc, char *chid, char *palette); + extern int ImageOut(options_t *opts, image_t *img, int offset, int width, char *desc, char chid, char *palette); ImageOut(&options, &distrib, 0, 256, "Distribution", chid, NULL); } diff --git a/main.c b/main.c index 1aaca5f..c75f039 100644 --- a/main.c +++ b/main.c @@ -36,7 +36,7 @@ extern int getpixelrow(float *pixelv, int nrow, int *zenith, int reset); // I/O extern int readRawImage(char *filename, float **prow, int *nrow); -extern int ImageOut(options_t *opts, image_t *img, int offset, int width, char *desc, char *chid, char *palette); +extern int ImageOut(options_t *opts, image_t *img, int offset, int width, char *desc, char chid, char *palette); extern int initWriter(options_t *opts, image_t *img, int width, int height, char *desc, char *chid); extern void pushRow(float *row, int width); extern void closeWriter(); @@ -47,7 +47,7 @@ extern void histogramEqualise(float **prow, int nrow, int offset, int width); extern void linearEnhance(float **prow, int nrow, int offset, int width); extern void temperature(options_t *opts, image_t *img, int offset, int width); extern void denoise(float **prow, int nrow, int offset, int width); -extern void distrib(options_t *opts, image_t *img, char *chid); +extern void distrib(options_t *opts, image_t *img, char chid); extern void flipImage(image_t *img, int width, int offset); // Palettes @@ -74,11 +74,11 @@ int main(int argc, char **argv) { usage(); } - options_t opts = { "r", "", 19, "", ".", 0, "" }; + options_t opts = { "r", "", 19, "", ".", 0, "", "", 1.0 }; // Parse arguments int opt; - while ((opt = getopt(argc, argv, "o:m:d:i:s:e:rp:")) != EOF) { + while ((opt = getopt(argc, argv, "o:m:d:i:s:e:p:g:r")) != EOF) { switch (opt) { case 'd': opts.path = optarg; @@ -108,6 +108,9 @@ int main(int argc, char **argv) { case 'p': opts.palette = optarg; break; + case 'g': + opts.gamma = atof(optarg); + break; default: usage(); } @@ -296,7 +299,7 @@ static int initsnd(char *filename) { return 1; } -// Read samples from the wave file +// Read samples from the audio file int getsample(float *sample, int nb) { if(channels == 1){ return sf_read_float(audioFile, sample, nb); @@ -335,6 +338,7 @@ static void usage(void) { " -m Map file\n" " -p Path to palette\n" " -r Realtime decode\n" + " -g Gamma adjustment (1.0 = off)\n" "\nRefer to the README for more infomation\n"); exit(EINVAL); diff --git a/pngio.c b/pngio.c index 3631027..414ef74 100644 --- a/pngio.c +++ b/pngio.c @@ -100,12 +100,12 @@ int mapOverlay(char *filename, rgb_t **crow, int nrow, int zenith, int MCIR) { if(MCIR){ if(map.b < 128 && map.g > 128){ // Land - float green = CLIP((map.g-256)/32.0, 0, 1); - float blue = 1 - CLIP((map.b-32)/64.0, 0, 1); - crow[y][cha] = (rgb_t){blue*127, 30+green*80, 40}; + float green = CLIP(map.g/300, 0, 1); + float blue = 0.15 - CLIP(map.b/960.0, 0, 1); + crow[y][cha] = (rgb_t){blue*1000, green*98, blue*500.0}; }else{ // Sea - crow[y][cha] = (rgb_t){12, 30, 85}; + crow[y][cha] = (rgb_t){9, 17, 74}; } } @@ -125,7 +125,7 @@ int mapOverlay(char *filename, rgb_t **crow, int nrow, int zenith, int MCIR) { // Cloud overlay on channel A if(MCIR){ - float cloud = CLIP((crow[y][chb].r - 115) / 107, 0, 1); + float cloud = CLIP((crow[y][chb].r - 105) / 150, 0, 1); crow[y][cha] = RGBcomposite((rgb_t){240, 250, 255}, cloud, crow[y][cha], 1); } } @@ -409,6 +409,11 @@ int ImageOut(options_t *opts, image_t *img, int offset, int width, char *desc, c printf("Writing %s", outName); + + // Float power macro (for gamma adjustment) + #define POWF(a, b) (b == 1.0 ? a : exp(b * log(a))) + float a = POWF(255, opts->gamma)/255; + // Build image for (int y = 0; y < img->nrow; y++) { png_color pix[width]; // Color @@ -416,17 +421,16 @@ int ImageOut(options_t *opts, image_t *img, int offset, int width, char *desc, c int skip = 0; for (int x = 0; x < width; x++) { - if(crop_telemetry && x == CH_WIDTH){ + if(crop_telemetry && x == CH_WIDTH) skip += TELE_WIDTH + SYNC_WIDTH + SPC_WIDTH; - } if(greyscale){ - mpix[x] = img->prow[y][x + skip + offset]; + mpix[x] = POWF(img->prow[y][x + skip + offset], opts->gamma)/a; }else{ pix[x] = (png_color){ - crow[y][x + skip + offset].r, - crow[y][x + skip + offset].g, - crow[y][x + skip + offset].b + POWF(crow[y][x + skip + offset].r, opts->gamma)/a, + POWF(crow[y][x + skip + offset].g, opts->gamma)/a, + POWF(crow[y][x + skip + offset].b, opts->gamma)/a }; } }