Переглянути джерело

Export offsets as needed for image functions

tags/v1.8.0
Jon Beniston 3 роки тому
джерело
коміт
328ea956f4
6 змінених файлів з 62 додано та 81 видалено
  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 Переглянути файл

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


+ 11
- 12
src/image.c Переглянути файл

@@ -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], &regr);
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) {


+ 19
- 20
src/main.c Переглянути файл

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


+ 0
- 29
src/offsets.h Переглянути файл

@@ -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 Переглянути файл

@@ -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];



+ 0
- 1
src/pngio.h Переглянути файл

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


Завантаження…
Відмінити
Зберегти