Skip to content

Commit

Permalink
Add color mode
Browse files Browse the repository at this point in the history
  • Loading branch information
tom2238 committed Sep 9, 2019
1 parent 2d49080 commit 268e369
Show file tree
Hide file tree
Showing 19 changed files with 583 additions and 50 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Debug/
apt_audio
noaa_apt
imgc
apt-colorm
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ Information and description:

```
NOAA automatic picture transmission (APT) encoder
Usage: Debug/noaa_apt (-i <file> [-s <file>] | -I) [(-d <device> | -O) -m <mode> -lcr]
Usage: Debug/noaa_apt (-i <file> [-s <file>] | -I) [(-d <device> | -O) -m <mode> -lcrM]
-i <filename> Input TGA image (909px width, 24bit RGB)
-s <filename> Second input TGA image (B channel, mode ignored)
-d <device> OSS audio device (default /dev/dsp) or file
-m <mode> Channel B data mode (R,G,B,N,Y)
-m <mode> Channel B data mode (R,G,B,N,Y,C)
-I Read image data from stdin
-O Write audio data to stdout
-M Multi image reading from stdin
-l Enable infinite image loop
-c Enable user console
-r Device is regular file (write WAV audio file)
-h Show this help
Build: 00:35:30 Jul 26 2019, GCC 5.3.0
Build: 21:52:59 Aug 18 2019, GCC 5.3.0
```

* Run as: ```guest@porteus:~$ padsp noaa_apt -lci SourceTestImage.tga```
Expand All @@ -33,6 +34,18 @@ Usage: Debug/noaa_apt (-i <file> [-s <file>] | -I) [(-d <device> | -O) -m <mode>
<tr><td>Source audio</td><td><audio src="./doc/SourceTestAudio.ogg" controls preload="none"></audio> <a href="./doc/SourceTestAudio.ogg">Sample</a></td></tr>
</table>

### Special mode C - color

Mode use 12bit (4096 colors, square root of 4096 is 64) look up table. Each color have 4 bit resolution (16 values). Channel A contain Y-pos values and channel B contain X-pos values (position in LUT). Image quality depends on LUT (color position in table). Current LUT is not ideal. Only X-pos is good. For decoding use apt-colorm and for better image quality disable gamma correction in WxToImg.

<table>
<tr><td>Look up table (64x64, upscaled 4x)</td><td><img src="./doc/test-space-4k-lines.png" width="256"></td></tr>
<tr><td>Original image</td><td><img src="./doc/139-orig.png" width="500"></td></tr>
<tr><td>Channel A image</td><td><img src="./doc/139-color-a.png" width="500"></td></tr>
<tr><td>Channel B image</td><td><img src="./doc/139-color-b.png" width="500"></td></tr>
<tr><td>Decoded color image</td><td><img src="./doc/139-color-decoded.png" width="500"></td></tr>
</table>

### APT

APT means Automatic Picture Transmission. It is a system, developed in the 1960s, made to transmit low-resolution analog image for weather satellites. A complete APT image takes around 12 minutes to be built up at a rate of 2 lines per second. The data is broadcasted by the satellite. The stream is obtained by the AVHRR/3 instrument. Two channels with a low resolution are emitting all the time using VHF signals at reduced rates (around 120 lines/minutes).
Expand Down
105 changes: 105 additions & 0 deletions apt-colorm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <math.h>
#include <getopt.h>
#include "image.h"
#include "aptcode.h"

#define _APT_FILE_NO_SET "σame"

void Usage(char *p_name);

int main(int argc, char *argv[]) {
if(argc == 1){
Usage(argv[0]);
return 0;
}
char channel_a[1024]=_APT_FILE_NO_SET;
char channel_b[1024]=_APT_FILE_NO_SET;
char output[1024]=_APT_FILE_NO_SET;
int opt = 0;
while ((opt = getopt(argc, argv, "a:b:o:h")) != -1){
switch (opt) {
case 'h': //Help
Usage(argv[0]);
return 0;
break;
case 'a': //Channel A TGA image
strncpy(channel_a,optarg,sizeof(channel_a)-1);
break;
case 'b': //Channel B TGA image
strncpy(channel_b,optarg,sizeof(channel_b)-1);
break;
case 'o': //Output TGA image
strncpy(output,optarg,sizeof(output)-1);
break;
default:
Usage(argv[0]);
return 0;
}
}
if(strncmp(channel_a,_APT_FILE_NO_SET,4) == 0) {
printf("%s: required argument and option -- '-a <filename>'\n",argv[0]);
exit(2);
}
if(strncmp(channel_b,_APT_FILE_NO_SET,4) == 0) {
printf("%s: required argument and option -- '-b <filename>'\n",argv[0]);
exit(2);
}
if(strncmp(output,_APT_FILE_NO_SET,4) == 0) {
printf("%s: required argument and option -- '-o <filename>'\n",argv[0]);
exit(2);
}
TgaImageHead ChannelA, ChannelB, OutputColor;
ChannelA = OpenTgaImage(channel_a);
ChannelB = OpenTgaImage(channel_b);
OutputColor = ChannelA;
OutputColor = WriteTgaImage(output, OutputColor);
if(ChannelA.File == NULL) { // On error
exit(1);
}
if(ChannelB.File == NULL) { // On error
exit(1);
}
if(OutputColor.File == NULL) { // On error
exit(1);
}

int i,j;
unsigned int pix_a;
unsigned int pix_b;
HsvColor hsvc;
AptColor aptc;
RgbColor rgbc;
// 24 bit RGB, but in grayscale expected
for(i=0;i<ChannelA.Width;i++) {
for(j=0;j<ChannelA.Height;j++) {
pix_a = ReadTGAPixel(ChannelA.File);
pix_b = ReadTGAPixel(ChannelB.File);
aptc.h = GetRedSubPixel(pix_a); // X
aptc.sv = GetRedSubPixel(pix_b); // Y

rgbc = AptToRgb(aptc);

WriteTGAPixel(rgbc.r,rgbc.g,rgbc.b, OutputColor.File);
}
}
fclose(ChannelA.File);
fclose(ChannelB.File);
fclose(OutputColor.File);
return 0;
}

void Usage(char *p_name) {
printf("NOAA color mode decoder\n");
printf("Usage: %s -a <filename> -b <filename> -o <filename> -h\n",p_name);
printf(" -a <filename> Input channel A TGA image (909px width, 24bit RGB)\n");
printf(" -b <filename> Input channel B TGA image (909px width, 24bit RGB)\n");
printf(" -o <filename> Output color TGA image \n");
printf(" -h Show this help\n");
printf(" Build: %s %s, GCC %s\n", __TIME__, __DATE__, __VERSION__);
}

2 changes: 2 additions & 0 deletions apt-colorm.make
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
gcc apt-colorm.c image.c -Wall -o apt-colorm -std=c99
14 changes: 13 additions & 1 deletion aptcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ AptLine CreateAptLine(uint8_t frame, uint8_t currentline, AptTelemetry ChanA, Ap
uint8_t Rval = 0;
uint8_t Gval = 0;
uint8_t Bval = 0;
RgbColor pixel_r;
AptColor pixel_a;
unsigned int pix;
// Sync A and Sync B
for(i=0;i<APT_SYNC_A;i++) {
Expand All @@ -84,7 +86,9 @@ AptLine CreateAptLine(uint8_t frame, uint8_t currentline, AptTelemetry ChanA, Ap
Rval = GetRedSubPixel(pix);
Gval = GetGreenSubPixel(pix);
Bval = GetBlueSubPixel(pix);
NewLine.VideoA[j] = Rval*0.302 + Gval*0.59 + Bval*0.11;
if(DataB!='C') {
NewLine.VideoA[j] = Rval*0.302 + Gval*0.59 + Bval*0.11;
}
switch(DataB) {
case 'R': //Red
NewLine.VideoB[j] = Rval;
Expand All @@ -98,6 +102,14 @@ AptLine CreateAptLine(uint8_t frame, uint8_t currentline, AptTelemetry ChanA, Ap
case 'Y': //Yb
NewLine.VideoB[j] = (-38*Rval-74*Gval+112*Bval+128)/256 + 128;
break;
case 'C': //Color
pixel_r.r = Rval;
pixel_r.g = Gval;
pixel_r.b = Bval;
pixel_a = RgbToApt(pixel_r);
NewLine.VideoA[j] = pixel_a.h;
NewLine.VideoB[j] = pixel_a.sv;
break;
case 'N':
default : //Negative
NewLine.VideoB[j] = 255-NewLine.VideoA[j];
Expand Down
Binary file added doc/139-color-a.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/139-color-b.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/139-color-decoded.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/139-orig.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/test-space-4k-lines.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions image.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,4 +304,32 @@ HsvColor AptToHsv(AptColor apt, uint8_t bits) {
}

return hsv;
}

AptColor RgbToApt(RgbColor rgb) {
AptColor apt;
uint8_t R = (rgb.r >> 4) & 0xF;
uint8_t G = (rgb.g >> 4) & 0xF;
uint8_t B = (rgb.b >> 4) & 0xF;
uint16_t val = (R << 8) + (G << 4) + B;
uint16_t pos = LUTFromRgb[val];
uint16_t y_val = pos % 64;
uint16_t x_val = (pos - y_val) / 64;
apt.h = (x_val & 0x3F) * 4;
apt.sv = (y_val & 0x3F) * 4;
return apt;
}

RgbColor AptToRgb(AptColor apt) {
RgbColor rgb;
uint8_t x_val = (apt.h+2)/4;
uint8_t y_val = (apt.sv+2)/4;
if(x_val > 255) {x_val = 255;}
if(y_val > 255) {y_val = 255;}
uint16_t val = LUTFromApt[x_val][y_val];
uint8_t R = (val >> 8) & 0xF;
uint8_t G = (val >> 4) & 0xF;
uint8_t B = (val >> 0) & 0xF;
rgb.r = R * 17; rgb.g = G * 17; rgb.b = B * 17;
return rgb;
}
4 changes: 4 additions & 0 deletions image.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef NA_IMAGE_R_H_
#define NA_IMAGE_R_H_

#include "imgtable.h"
#include "imgtable_apt.h"
#define IMG_TGA_HEAD_SIZE 18

typedef struct {
Expand Down Expand Up @@ -62,4 +64,6 @@ RgbColor HsvToRgb(HsvColor hsv);
AptColor HsvToApt(HsvColor hsv, uint8_t bits);
//Convert APT to HSV color space
HsvColor AptToHsv(AptColor apt, uint8_t bits);
AptColor RgbToApt(RgbColor rgb);
RgbColor AptToRgb(AptColor apt);
#endif
Loading

0 comments on commit 268e369

Please sign in to comment.