Browse Source

Export offsets as needed for image functions

tags/v1.8.0
Jon Beniston 3 years ago
parent
commit
328ea956f4
6 changed files with 62 additions and 81 deletions
  1. +13
    -0
      src/apt.h
  2. +11
    -12
      src/image.c
  3. +19
    -20
      src/main.c
  4. +0
    -29
      src/offsets.h
  5. +19
    -19
      src/pngio.c
  6. +0
    -1
      src/pngio.h

+ 13
- 0
src/apt.h View File

@@ -41,6 +41,19 @@ extern "C" {


// Maximum height of an APT image in number of scanlines // Maximum height of an APT image in number of scanlines
#define APT_MAX_HEIGHT 3000 #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. // apt_getpixelrow callback function to get audio samples.
// context is the same as passed to apt_getpixelrow. // context is the same as passed to apt_getpixelrow.


+ 11
- 12
src/image.c View File

@@ -23,7 +23,6 @@
#include <stdlib.h> #include <stdlib.h>


#include "apt.h" #include "apt.h"
#include "offsets.h"
#include "libs/reg.h" #include "libs/reg.h"
#include "image.h" #include "image.h"


@@ -106,10 +105,10 @@ void apt_linearEnhance(float **prow, int nrow, int offset, int width){


// Brightness calibrate, including telemetry // Brightness calibrate, including telemetry
void calibrateImage(float **prow, int nrow, int offset, int width, rgparam_t regr){ 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 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], &regr); float pv = (float)rgcal(prow[y][x + offset], &regr);
prow[y][x + offset] = CLIP(pv, 0, 255); 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) { int apt_calibrate(float **prow, int nrow, int offset, int width) {
double teleline[APT_MAX_HEIGHT] = { 0.0 }; double teleline[APT_MAX_HEIGHT] = { 0.0 };
double wedge[16]; 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 telestart, mtelestart = 0;
int channel = -1; 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 // 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"); fprintf(stderr, "Telemetry decoding error, not enough rows\n");
return 0; return 0;
} }
@@ -177,7 +176,7 @@ int apt_calibrate(float **prow, int nrow, int offset, int width) {
// Find the least noisy frame // Find the least noisy frame
double minNoise = -1; double minNoise = -1;
int bestFrame = -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; int j;


for (j = 0; j < 16; 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 // Find the brightness of the minute marker, I don't really know what for
Cs = 0.0; Cs = 0.0;
int i, j = n; 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; float csline = 0.0;
for (int l = 3; l < 43; l++) 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; csline /= 40.0;


if (csline > 50.0) { if (csline > 50.0) {
@@ -286,10 +285,10 @@ int apt_cropNoise(apt_image_t *img){
float spc_rows[APT_MAX_HEIGHT] = { 0.0 }; float spc_rows[APT_MAX_HEIGHT] = { 0.0 };
int startCrop = 0; int endCrop = img->nrow; int startCrop = 0; int endCrop = img->nrow;
for(int y = 0; y < img->nrow; y++) { 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 // Skip minute markings
if(spc_rows[y] < 10) { if(spc_rows[y] < 10) {


+ 19
- 20
src/main.c View File

@@ -31,7 +31,6 @@
#include <time.h> #include <time.h>
#include "libs/argparse.h" #include "libs/argparse.h"


#include "offsets.h"
#include "common.h" #include "common.h"
#include "apt.h" #include "apt.h"


@@ -144,7 +143,7 @@ static int processAudio(char *filename, options_t *opts){
strncpy(img.name, ctime(&t), 24); strncpy(img.name, ctime(&t), 24);


// Init a row writer // 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){ 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) if (apt_getpixelrow(img.prow[img.nrow], img.nrow, &img.zenith, (img.nrow == 0), getsamples, NULL) == 0)
break; 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); fprintf(stderr, "Row: %d\r", img.nrow);
fflush(stderr); fflush(stderr);
@@ -190,8 +189,8 @@ static int processAudio(char *filename, options_t *opts){
} }


// Calibrate // 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 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]); 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 // Denoise
if(CONTAINS(opts->effects, 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 // Flip, for northbound passes
if(CONTAINS(opts->effects, Flip_Image)){ 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 // Temperature
@@ -222,49 +221,49 @@ static int processAudio(char *filename, options_t *opts){
} }


// Perform temperature calibration // 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 // MCIR
if (CONTAINS(opts->type, 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 // Linear equalise
if(CONTAINS(opts->effects, 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 // Histogram equalise
if(CONTAINS(opts->effects, 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 // Raw image
if (CONTAINS(opts->type, 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]); 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 // Palette image
if (CONTAINS(opts->type, Palleted)) { if (CONTAINS(opts->type, Palleted)) {
img.palette = opts->palette; img.palette = opts->palette;
strcpy(desc, "Palette composite"); 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 // Channel A
if (CONTAINS(opts->type, Channel_A)) { if (CONTAINS(opts->type, Channel_A)) {
sprintf(desc, "%s (%s)", ch.id[img.chA], ch.name[img.chA]); 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 // Channel B
if (CONTAINS(opts->type, Channel_B)) { if (CONTAINS(opts->type, Channel_B)) {
sprintf(desc, "%s (%s)", ch.id[img.chB], ch.name[img.chB]); 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; return 1;


+ 0
- 29
src/offsets.h View File

@@ -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)

+ 19
- 19
src/pngio.c View File

@@ -95,7 +95,7 @@ int mapOverlay(char *filename, apt_rgb_t **crow, int nrow, int zenith, int MCIR)
}; };


// Pixel offsets // Pixel offsets
int chb = x + CHB_OFFSET - 49;
int chb = x + APT_CHB_OFFSET - 49;
int cha = x + 36; int cha = x + 36;


// Fill in map // 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); png_byte bit_depth = png_get_bit_depth(png, info);


// Check the image // 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; return 0;
}else if(bit_depth != 8){ }else if(bit_depth != 8){
fprintf(stderr, "Raw image must have 8 bit color.\n"); 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){ void prow2crow(float **prow, int nrow, char *palette, apt_rgb_t **crow){
for(int y = 0; y < nrow; y++){ 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) if(palette == NULL)
crow[y][x].r = crow[y][x].g = crow[y][x].b = prow[y][x]; crow[y][x].r = crow[y][x].g = crow[y][x].b = prow[y][x];
else 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 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++){ for(unsigned long int i = 0; i < strlen(opts->effects); i++){
switch (opts->effects[i]) { switch (opts->effects[i]) {
case Crop_Telemetry: 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; crop_telemetry = 1;
break; break;
case Precipitation_Overlay: case Precipitation_Overlay:
@@ -422,9 +422,9 @@ int ImageOut(options_t *opts, apt_image_t *img, int offset, int width, char *des
// Precipitation overlay // Precipitation overlay
if(CONTAINS(opts->effects, Precipitation_Overlay)){ if(CONTAINS(opts->effects, Precipitation_Overlay)){
for(int y = 0; y < img->nrow; y++){ 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 // Build image
for (int y = 0; y < img->nrow; y++) { 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; int skip = 0;
for (int x = 0; x < width; x++) { 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){ if(greyscale){
mpix[x] = POWF(img->prow[y][x + skip + offset], opts->gamma)/a; 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){ void pushRow(float *row, int width){
png_byte pix[IMG_WIDTH];
png_byte pix[APT_IMG_WIDTH];
for(int i = 0; i < width; i++) for(int i = 0; i < width; i++)
pix[i] = row[i]; pix[i] = row[i];




+ 0
- 1
src/pngio.h View File

@@ -1,6 +1,5 @@
#include "apt.h" #include "apt.h"
#include "common.h" #include "common.h"
#include "offsets.h"


int mapOverlay(char *filename, apt_rgb_t **crow, int nrow, int zenith, int MCIR); int mapOverlay(char *filename, apt_rgb_t **crow, int nrow, int zenith, int MCIR);
int readRawImage(char *filename, float **prow, int *nrow); int readRawImage(char *filename, float **prow, int *nrow);


Loading…
Cancel
Save