@@ -41,6 +41,19 @@ extern "C" { | |||
// Maximum height of an APT image in number of scanlines | |||
#define APT_MAX_HEIGHT 3000 | |||
#define APT_SYNC_WIDTH 39 | |||
#define APT_SPC_WIDTH 47 | |||
#define APT_TELE_WIDTH 45 | |||
// Width in pixels of a single channel image | |||
#define APT_CH_WIDTH 909 | |||
#define APT_FRAME_LEN 128 | |||
#define APT_CH_OFFSET (APT_SYNC_WIDTH+APT_SPC_WIDTH+APT_CH_WIDTH+APT_TELE_WIDTH) | |||
#define APT_IMG_WIDTH 2080 | |||
// Offset in pixels to channel A | |||
#define APT_CHA_OFFSET (APT_SYNC_WIDTH+APT_SPC_WIDTH) | |||
// Offset in pixels to channel B | |||
#define APT_CHB_OFFSET (APT_SYNC_WIDTH+APT_SPC_WIDTH+APT_CH_WIDTH+APT_TELE_WIDTH+APT_SYNC_WIDTH+APT_SPC_WIDTH) | |||
#define APT_TOTAL_TELE (APT_SYNC_WIDTH+APT_SPC_WIDTH+APT_TELE_WIDTH+APT_SYNC_WIDTH+APT_SPC_WIDTH+APT_TELE_WIDTH) | |||
// apt_getpixelrow callback function to get audio samples. | |||
// context is the same as passed to apt_getpixelrow. | |||
@@ -23,7 +23,6 @@ | |||
#include <stdlib.h> | |||
#include "apt.h" | |||
#include "offsets.h" | |||
#include "libs/reg.h" | |||
#include "image.h" | |||
@@ -106,10 +105,10 @@ void apt_linearEnhance(float **prow, int nrow, int offset, int width){ | |||
// Brightness calibrate, including telemetry | |||
void calibrateImage(float **prow, int nrow, int offset, int width, rgparam_t regr){ | |||
offset -= SYNC_WIDTH+SPC_WIDTH; | |||
offset -= APT_SYNC_WIDTH+APT_SPC_WIDTH; | |||
for (int y = 0; y < nrow; y++) { | |||
for (int x = 0; x < width+SYNC_WIDTH+SPC_WIDTH+TELE_WIDTH; x++) { | |||
for (int x = 0; x < width+APT_SYNC_WIDTH+APT_SPC_WIDTH+APT_TELE_WIDTH; x++) { | |||
float pv = (float)rgcal(prow[y][x + offset], ®r); | |||
prow[y][x + offset] = CLIP(pv, 0, 255); | |||
} | |||
@@ -129,7 +128,7 @@ double teleNoise(double wedges[16]){ | |||
int apt_calibrate(float **prow, int nrow, int offset, int width) { | |||
double teleline[APT_MAX_HEIGHT] = { 0.0 }; | |||
double wedge[16]; | |||
rgparam_t regr[APT_MAX_HEIGHT/FRAME_LEN + 1]; | |||
rgparam_t regr[APT_MAX_HEIGHT/APT_FRAME_LEN + 1]; | |||
int telestart, mtelestart = 0; | |||
int channel = -1; | |||
@@ -166,10 +165,10 @@ int apt_calibrate(float **prow, int nrow, int offset, int width) { | |||
} | |||
} | |||
telestart = (mtelestart + 64) % FRAME_LEN; | |||
telestart = (mtelestart + 64) % APT_FRAME_LEN; | |||
// Make sure that theres at least one full frame in the image | |||
if (nrow < telestart + FRAME_LEN) { | |||
if (nrow < telestart + APT_FRAME_LEN) { | |||
fprintf(stderr, "Telemetry decoding error, not enough rows\n"); | |||
return 0; | |||
} | |||
@@ -177,7 +176,7 @@ int apt_calibrate(float **prow, int nrow, int offset, int width) { | |||
// Find the least noisy frame | |||
double minNoise = -1; | |||
int bestFrame = -1; | |||
for (int n = telestart, k = 0; n < nrow - FRAME_LEN; n += FRAME_LEN, k++) { | |||
for (int n = telestart, k = 0; n < nrow - APT_FRAME_LEN; n += APT_FRAME_LEN, k++) { | |||
int j; | |||
for (j = 0; j < 16; j++) { | |||
@@ -217,10 +216,10 @@ int apt_calibrate(float **prow, int nrow, int offset, int width) { | |||
// Find the brightness of the minute marker, I don't really know what for | |||
Cs = 0.0; | |||
int i, j = n; | |||
for (i = 0, j = n; j < n + FRAME_LEN; j++) { | |||
for (i = 0, j = n; j < n + APT_FRAME_LEN; j++) { | |||
float csline = 0.0; | |||
for (int l = 3; l < 43; l++) | |||
csline += prow[n][l + offset - SPC_WIDTH]; | |||
csline += prow[n][l + offset - APT_SPC_WIDTH]; | |||
csline /= 40.0; | |||
if (csline > 50.0) { | |||
@@ -286,10 +285,10 @@ int apt_cropNoise(apt_image_t *img){ | |||
float spc_rows[APT_MAX_HEIGHT] = { 0.0 }; | |||
int startCrop = 0; int endCrop = img->nrow; | |||
for(int y = 0; y < img->nrow; y++) { | |||
for(int x = 0; x < SPC_WIDTH; x++) { | |||
spc_rows[y] += img->prow[y][x + (CHB_OFFSET - SPC_WIDTH)]; | |||
for(int x = 0; x < APT_SPC_WIDTH; x++) { | |||
spc_rows[y] += img->prow[y][x + (APT_CHB_OFFSET - APT_SPC_WIDTH)]; | |||
} | |||
spc_rows[y] /= SPC_WIDTH; | |||
spc_rows[y] /= APT_SPC_WIDTH; | |||
// Skip minute markings | |||
if(spc_rows[y] < 10) { | |||
@@ -31,7 +31,6 @@ | |||
#include <time.h> | |||
#include "libs/argparse.h" | |||
#include "offsets.h" | |||
#include "common.h" | |||
#include "apt.h" | |||
@@ -144,7 +143,7 @@ static int processAudio(char *filename, options_t *opts){ | |||
strncpy(img.name, ctime(&t), 24); | |||
// Init a row writer | |||
initWriter(opts, &img, IMG_WIDTH, APT_MAX_HEIGHT, "Unprocessed realtime image", "r"); | |||
initWriter(opts, &img, APT_IMG_WIDTH, APT_MAX_HEIGHT, "Unprocessed realtime image", "r"); | |||
} | |||
if(strcmp(extension, "png") == 0){ | |||
@@ -168,7 +167,7 @@ static int processAudio(char *filename, options_t *opts){ | |||
if (apt_getpixelrow(img.prow[img.nrow], img.nrow, &img.zenith, (img.nrow == 0), getsamples, NULL) == 0) | |||
break; | |||
if(opts->realtime) pushRow(img.prow[img.nrow], IMG_WIDTH); | |||
if(opts->realtime) pushRow(img.prow[img.nrow], APT_IMG_WIDTH); | |||
fprintf(stderr, "Row: %d\r", img.nrow); | |||
fflush(stderr); | |||
@@ -190,8 +189,8 @@ static int processAudio(char *filename, options_t *opts){ | |||
} | |||
// Calibrate | |||
img.chA = apt_calibrate(img.prow, img.nrow, CHA_OFFSET, CH_WIDTH); | |||
img.chB = apt_calibrate(img.prow, img.nrow, CHB_OFFSET, CH_WIDTH); | |||
img.chA = apt_calibrate(img.prow, img.nrow, APT_CHA_OFFSET, APT_CH_WIDTH); | |||
img.chB = apt_calibrate(img.prow, img.nrow, APT_CHB_OFFSET, APT_CH_WIDTH); | |||
printf("Channel A: %s (%s)\n", ch.id[img.chA], ch.name[img.chA]); | |||
printf("Channel B: %s (%s)\n", ch.id[img.chB], ch.name[img.chB]); | |||
@@ -202,14 +201,14 @@ static int processAudio(char *filename, options_t *opts){ | |||
// Denoise | |||
if(CONTAINS(opts->effects, Denoise)){ | |||
apt_denoise(img.prow, img.nrow, CHA_OFFSET, CH_WIDTH); | |||
apt_denoise(img.prow, img.nrow, CHB_OFFSET, CH_WIDTH); | |||
apt_denoise(img.prow, img.nrow, APT_CHA_OFFSET, APT_CH_WIDTH); | |||
apt_denoise(img.prow, img.nrow, APT_CHB_OFFSET, APT_CH_WIDTH); | |||
} | |||
// Flip, for northbound passes | |||
if(CONTAINS(opts->effects, Flip_Image)){ | |||
apt_flipImage(&img, CH_WIDTH, CHA_OFFSET); | |||
apt_flipImage(&img, CH_WIDTH, CHB_OFFSET); | |||
apt_flipImage(&img, APT_CH_WIDTH, APT_CHA_OFFSET); | |||
apt_flipImage(&img, APT_CH_WIDTH, APT_CHB_OFFSET); | |||
} | |||
// Temperature | |||
@@ -222,49 +221,49 @@ static int processAudio(char *filename, options_t *opts){ | |||
} | |||
// Perform temperature calibration | |||
temperature(opts, &tmpimg, CHB_OFFSET, CH_WIDTH); | |||
ImageOut(opts, &tmpimg, CHB_OFFSET, CH_WIDTH, "Temperature", Temperature, (char *)apt_TempPalette); | |||
temperature(opts, &tmpimg, APT_CHB_OFFSET, APT_CH_WIDTH); | |||
ImageOut(opts, &tmpimg, APT_CHB_OFFSET, APT_CH_WIDTH, "Temperature", Temperature, (char *)apt_TempPalette); | |||
} | |||
// MCIR | |||
if (CONTAINS(opts->type, MCIR)) | |||
ImageOut(opts, &img, CHA_OFFSET, CH_WIDTH, "MCIR", MCIR, NULL); | |||
ImageOut(opts, &img, APT_CHA_OFFSET, APT_CH_WIDTH, "MCIR", MCIR, NULL); | |||
// Linear equalise | |||
if(CONTAINS(opts->effects, Linear_Equalise)){ | |||
apt_linearEnhance(img.prow, img.nrow, CHA_OFFSET, CH_WIDTH); | |||
apt_linearEnhance(img.prow, img.nrow, CHB_OFFSET, CH_WIDTH); | |||
apt_linearEnhance(img.prow, img.nrow, APT_CHA_OFFSET, APT_CH_WIDTH); | |||
apt_linearEnhance(img.prow, img.nrow, APT_CHB_OFFSET, APT_CH_WIDTH); | |||
} | |||
// Histogram equalise | |||
if(CONTAINS(opts->effects, Histogram_Equalise)){ | |||
apt_histogramEqualise(img.prow, img.nrow, CHA_OFFSET, CH_WIDTH); | |||
apt_histogramEqualise(img.prow, img.nrow, CHB_OFFSET, CH_WIDTH); | |||
apt_histogramEqualise(img.prow, img.nrow, APT_CHA_OFFSET, APT_CH_WIDTH); | |||
apt_histogramEqualise(img.prow, img.nrow, APT_CHB_OFFSET, APT_CH_WIDTH); | |||
} | |||
// Raw image | |||
if (CONTAINS(opts->type, Raw_Image)) { | |||
sprintf(desc, "%s (%s) & %s (%s)", ch.id[img.chA], ch.name[img.chA], ch.id[img.chB], ch.name[img.chB]); | |||
ImageOut(opts, &img, 0, IMG_WIDTH, desc, Raw_Image, NULL); | |||
ImageOut(opts, &img, 0, APT_IMG_WIDTH, desc, Raw_Image, NULL); | |||
} | |||
// Palette image | |||
if (CONTAINS(opts->type, Palleted)) { | |||
img.palette = opts->palette; | |||
strcpy(desc, "Palette composite"); | |||
ImageOut(opts, &img, CHA_OFFSET, 909, desc, Palleted, NULL); | |||
ImageOut(opts, &img, APT_CHA_OFFSET, 909, desc, Palleted, NULL); | |||
} | |||
// Channel A | |||
if (CONTAINS(opts->type, Channel_A)) { | |||
sprintf(desc, "%s (%s)", ch.id[img.chA], ch.name[img.chA]); | |||
ImageOut(opts, &img, CHA_OFFSET, CH_WIDTH, desc, Channel_A, NULL); | |||
ImageOut(opts, &img, APT_CHA_OFFSET, APT_CH_WIDTH, desc, Channel_A, NULL); | |||
} | |||
// Channel B | |||
if (CONTAINS(opts->type, Channel_B)) { | |||
sprintf(desc, "%s (%s)", ch.id[img.chB], ch.name[img.chB]); | |||
ImageOut(opts, &img, CHB_OFFSET, CH_WIDTH, desc, Channel_B, NULL); | |||
ImageOut(opts, &img, APT_CHB_OFFSET, APT_CH_WIDTH, desc, Channel_B, NULL); | |||
} | |||
return 1; | |||
@@ -1,29 +0,0 @@ | |||
/* | |||
* This file is part of Aptdec. | |||
* Copyright (c) 2004-2009 Thierry Leconte (F4DWV), Xerbo (xerbo@protonmail.com) 2019-2020 | |||
* | |||
* Aptdec 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. | |||
* | |||
* 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, see <https://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
#define SYNC_WIDTH 39 | |||
#define SPC_WIDTH 47 | |||
#define TELE_WIDTH 45 | |||
#define CH_WIDTH 909 | |||
#define FRAME_LEN 128 | |||
#define CH_OFFSET (SYNC_WIDTH+SPC_WIDTH+CH_WIDTH+TELE_WIDTH) | |||
#define IMG_WIDTH 2080 | |||
#define CHA_OFFSET (SYNC_WIDTH+SPC_WIDTH) | |||
#define CHB_OFFSET (SYNC_WIDTH+SPC_WIDTH+CH_WIDTH+TELE_WIDTH+SYNC_WIDTH+SPC_WIDTH) | |||
#define TOTAL_TELE (SYNC_WIDTH+SPC_WIDTH+TELE_WIDTH+SYNC_WIDTH+SPC_WIDTH+TELE_WIDTH) |
@@ -95,7 +95,7 @@ int mapOverlay(char *filename, apt_rgb_t **crow, int nrow, int zenith, int MCIR) | |||
}; | |||
// Pixel offsets | |||
int chb = x + CHB_OFFSET - 49; | |||
int chb = x + APT_CHB_OFFSET - 49; | |||
int cha = x + 36; | |||
// Fill in map | |||
@@ -170,8 +170,8 @@ int readRawImage(char *filename, float **prow, int *nrow) { | |||
png_byte bit_depth = png_get_bit_depth(png, info); | |||
// Check the image | |||
if(width != IMG_WIDTH){ | |||
fprintf(stderr, "Raw image must be %ipx wide.\n", IMG_WIDTH); | |||
if(width != APT_IMG_WIDTH){ | |||
fprintf(stderr, "Raw image must be %ipx wide.\n", APT_IMG_WIDTH); | |||
return 0; | |||
}else if(bit_depth != 8){ | |||
fprintf(stderr, "Raw image must have 8 bit color.\n"); | |||
@@ -281,9 +281,9 @@ int readPalette(char *filename, apt_rgb_t **pixels) { | |||
void prow2crow(float **prow, int nrow, char *palette, apt_rgb_t **crow){ | |||
for(int y = 0; y < nrow; y++){ | |||
crow[y] = (apt_rgb_t *) malloc(sizeof(apt_rgb_t) * IMG_WIDTH); | |||
crow[y] = (apt_rgb_t *) malloc(sizeof(apt_rgb_t) * APT_IMG_WIDTH); | |||
for(int x = 0; x < IMG_WIDTH; x++){ | |||
for(int x = 0; x < APT_IMG_WIDTH; x++){ | |||
if(palette == NULL) | |||
crow[y][x].r = crow[y][x].g = crow[y][x].b = prow[y][x]; | |||
else | |||
@@ -300,10 +300,10 @@ int applyUserPalette(float **prow, int nrow, char *filename, apt_rgb_t **crow){ | |||
} | |||
for(int y = 0; y < nrow; y++){ | |||
for(int x = 0; x < CH_WIDTH; x++){ | |||
int cha = CLIP(prow[y][x + CHA_OFFSET], 0, 255); | |||
int chb = CLIP(prow[y][x + CHB_OFFSET], 0, 255); | |||
crow[y][x + CHA_OFFSET] = pal_row[chb][cha]; | |||
for(int x = 0; x < APT_CH_WIDTH; x++){ | |||
int cha = CLIP(prow[y][x + APT_CHA_OFFSET], 0, 255); | |||
int chb = CLIP(prow[y][x + APT_CHB_OFFSET], 0, 255); | |||
crow[y][x + APT_CHA_OFFSET] = pal_row[chb][cha]; | |||
} | |||
} | |||
@@ -346,8 +346,8 @@ int ImageOut(options_t *opts, apt_image_t *img, int offset, int width, char *des | |||
for(unsigned long int i = 0; i < strlen(opts->effects); i++){ | |||
switch (opts->effects[i]) { | |||
case Crop_Telemetry: | |||
width -= TOTAL_TELE; | |||
offset += SYNC_WIDTH + SPC_WIDTH; | |||
width -= APT_TOTAL_TELE; | |||
offset += APT_SYNC_WIDTH + APT_SPC_WIDTH; | |||
crop_telemetry = 1; | |||
break; | |||
case Precipitation_Overlay: | |||
@@ -422,9 +422,9 @@ int ImageOut(options_t *opts, apt_image_t *img, int offset, int width, char *des | |||
// Precipitation overlay | |||
if(CONTAINS(opts->effects, Precipitation_Overlay)){ | |||
for(int y = 0; y < img->nrow; y++){ | |||
for(int x = 0; x < CH_WIDTH; x++){ | |||
if(img->prow[y][x + CHB_OFFSET] >= 198) | |||
crow[y][x + CHB_OFFSET] = crow[y][x + CHA_OFFSET] = apt_applyPalette(apt_PrecipPalette, img->prow[y][x + CHB_OFFSET]-198); | |||
for(int x = 0; x < APT_CH_WIDTH; x++){ | |||
if(img->prow[y][x + APT_CHB_OFFSET] >= 198) | |||
crow[y][x + APT_CHB_OFFSET] = crow[y][x + APT_CHA_OFFSET] = apt_applyPalette(apt_PrecipPalette, img->prow[y][x + APT_CHB_OFFSET]-198); | |||
} | |||
} | |||
} | |||
@@ -448,13 +448,13 @@ int ImageOut(options_t *opts, apt_image_t *img, int offset, int width, char *des | |||
// Build image | |||
for (int y = 0; y < img->nrow; y++) { | |||
png_color pix[IMG_WIDTH]; // Color | |||
png_byte mpix[IMG_WIDTH]; // Mono | |||
png_color pix[APT_IMG_WIDTH]; // Color | |||
png_byte mpix[APT_IMG_WIDTH]; // Mono | |||
int skip = 0; | |||
for (int x = 0; x < width; x++) { | |||
if(crop_telemetry && x == CH_WIDTH) | |||
skip += TELE_WIDTH + SYNC_WIDTH + SPC_WIDTH; | |||
if(crop_telemetry && x == APT_CH_WIDTH) | |||
skip += APT_TELE_WIDTH + APT_SYNC_WIDTH + APT_SPC_WIDTH; | |||
if(greyscale){ | |||
mpix[x] = POWF(img->prow[y][x + skip + offset], opts->gamma)/a; | |||
@@ -538,7 +538,7 @@ int initWriter(options_t *opts, apt_image_t *img, int width, int height, char *d | |||
} | |||
void pushRow(float *row, int width){ | |||
png_byte pix[IMG_WIDTH]; | |||
png_byte pix[APT_IMG_WIDTH]; | |||
for(int i = 0; i < width; i++) | |||
pix[i] = row[i]; | |||
@@ -1,6 +1,5 @@ | |||
#include "apt.h" | |||
#include "common.h" | |||
#include "offsets.h" | |||
int mapOverlay(char *filename, apt_rgb_t **crow, int nrow, int zenith, int MCIR); | |||
int readRawImage(char *filename, float **prow, int *nrow); | |||