You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

405 line
11 KiB

  1. /*
  2. * Aptdec
  3. * Copyright (c) 2004-2005 by Thierry Leconte (F4DWV)
  4. *
  5. * $Id$
  6. *
  7. * This library is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU Library General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Library General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Library General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. *
  21. */
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <getopt.h>
  26. #ifdef WIN32
  27. #include "w32util.h"
  28. #else
  29. #include <libgen.h>
  30. #endif
  31. #include <sndfile.h>
  32. #include <png.h>
  33. #include "version.h"
  34. #include "offsets.h"
  35. #include "temppalette.h"
  36. #include "gvipalette.h"
  37. extern int getpixelrow(float *pixelv);
  38. extern int init_dsp(double F);;
  39. static SNDFILE *inwav;
  40. static int initsnd(char *filename) {
  41. SF_INFO infwav;
  42. int res;
  43. /* open wav input file */
  44. infwav.format = 0;
  45. inwav = sf_open(filename, SFM_READ, &infwav);
  46. if (inwav == NULL) {
  47. fprintf(stderr, "Could not open %s for reading\n", filename);
  48. return (1);
  49. }
  50. res = init_dsp(infwav.samplerate);
  51. if(res < 0) {
  52. fprintf(stderr, "Sample rate too low: %d\n", infwav.samplerate);
  53. return (1);
  54. }
  55. if(res > 0) {
  56. fprintf(stderr, "Sample rate too hight: %d\n", infwav.samplerate);
  57. return (1);
  58. }
  59. fprintf(stderr, "Sample rate: %d\n", infwav.samplerate);
  60. if (infwav.channels != 1) {
  61. fprintf(stderr, "Too many channels in input file: %d\n", infwav.channels);
  62. return (1);
  63. }
  64. return (0);
  65. }
  66. int getsample(float *sample, int nb) {
  67. return (sf_read_float(inwav, sample, nb));
  68. }
  69. static png_text text_ptr[] = {
  70. {PNG_TEXT_COMPRESSION_NONE, "Software", version, sizeof(version)},
  71. {PNG_TEXT_COMPRESSION_NONE, "Channel", NULL, 0},
  72. {PNG_TEXT_COMPRESSION_NONE, "Description", "NOAA POES satellite image", 25}
  73. };
  74. static int ImageOut(char *filename, char *chid, float **prow, int nrow, int width, int offset, png_color *palette) {
  75. FILE *pngfile;
  76. png_infop info_ptr;
  77. png_structp png_ptr;
  78. int n;
  79. /* init png lib */
  80. png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  81. if (!png_ptr) {
  82. fprintf(stderr, "Could not create a PNG write struct\n");
  83. return (1);
  84. }
  85. info_ptr = png_create_info_struct(png_ptr);
  86. if (!info_ptr) {
  87. png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
  88. fprintf(stderr, "Could not create a PNG info struct\n");
  89. return (1);
  90. }
  91. if(palette == NULL) {
  92. /* greyscale */
  93. png_set_IHDR(png_ptr, info_ptr, width, nrow,
  94. 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
  95. PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  96. } else {
  97. /* palette color mage */
  98. png_set_IHDR(png_ptr, info_ptr, width, nrow,
  99. 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
  100. PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  101. png_set_PLTE(png_ptr, info_ptr, palette, 256);
  102. }
  103. text_ptr[1].text = chid;
  104. text_ptr[1].text_length = strlen(chid);
  105. png_set_text(png_ptr, info_ptr, text_ptr, 3);
  106. png_set_pHYs(png_ptr, info_ptr, 4000, 4000, PNG_RESOLUTION_METER);
  107. printf("Writing %s... ", filename);
  108. fflush(stdout);
  109. pngfile = fopen(filename, "wb");
  110. if (pngfile == NULL) {
  111. fprintf(stderr, "Could not open %s for writing\n", filename);
  112. return (1);
  113. }
  114. png_init_io(png_ptr, pngfile);
  115. png_write_info(png_ptr, info_ptr);
  116. for (n = 0; n < nrow; n++) {
  117. float *pixelv;
  118. png_byte pixel[2*IMG_WIDTH];
  119. int i;
  120. pixelv = prow[n];
  121. for (i = 0; i < width; i++) {
  122. pixel[i] = pixelv[i + offset];
  123. }
  124. png_write_row(png_ptr, pixel);
  125. }
  126. png_write_end(png_ptr, info_ptr);
  127. fclose(pngfile);
  128. printf("Done\n");
  129. png_destroy_write_struct(&png_ptr, &info_ptr);
  130. return (0);
  131. }
  132. static int ImageRGBOut(char *filename, float **prow, int nrow) {
  133. FILE *pngfile;
  134. png_infop info_ptr;
  135. png_structp png_ptr;
  136. int n;
  137. extern void falsecolor(double v, double t, float *r, float *g, float *b);
  138. /* init png lib */
  139. png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  140. if (!png_ptr) {
  141. fprintf(stderr, "Could not create a PNG write struct\n");
  142. return (1);
  143. }
  144. info_ptr = png_create_info_struct(png_ptr);
  145. if (!info_ptr) {
  146. png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
  147. fprintf(stderr, "Could not create a PNG info struct\n");
  148. return (1);
  149. }
  150. png_set_IHDR(png_ptr, info_ptr, CH_WIDTH , nrow ,
  151. 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
  152. PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  153. png_set_pHYs(png_ptr, info_ptr, 4000, 4000, PNG_RESOLUTION_METER);
  154. text_ptr[1].text = "False Color";
  155. text_ptr[1].text_length = strlen(text_ptr[1].text);
  156. png_set_text(png_ptr, info_ptr, text_ptr, 3);
  157. printf("Computing false color & writing: %s... ", filename);
  158. fflush(stdout);
  159. pngfile = fopen(filename, "wb");
  160. if (pngfile == NULL) {
  161. fprintf(stderr, "Could not open %s for writing\n", filename);
  162. return (1);
  163. }
  164. png_init_io(png_ptr, pngfile);
  165. png_write_info(png_ptr, info_ptr);
  166. for (n = 0; n < nrow ; n++) {
  167. png_color pix[CH_WIDTH];
  168. float *pixelc;
  169. int i;
  170. pixelc = prow[n];
  171. for (i = 0; i < CH_WIDTH - 1; i++) {
  172. float v, t;
  173. float r, g, b;
  174. v = pixelc[i+CHA_OFFSET];
  175. t = pixelc[i+CHB_OFFSET];
  176. falsecolor(v, t, &r, &g, &b);
  177. pix[i].red = 255.0 * r;
  178. pix[i].green = 255.0 * g;
  179. pix[i].blue = 255.0 * b;
  180. }
  181. png_write_row(png_ptr, (png_bytep) pix);
  182. }
  183. png_write_end(png_ptr, info_ptr);
  184. fclose(pngfile);
  185. printf("Done\n");
  186. png_destroy_write_struct(&png_ptr, &info_ptr);
  187. return (0);
  188. }
  189. static void Distrib(char *filename,float **prow,int nrow) {
  190. unsigned int distrib[256][256];
  191. int n;
  192. int x, y;
  193. int max = 0;
  194. FILE *df;
  195. for(y = 0; y < 256; y++)
  196. for(x = 0; x < 256; x++)
  197. distrib[y][x] = 0;
  198. for(n = 0; n < nrow; n++) {
  199. float *pixelv;
  200. int i;
  201. pixelv = prow[n];
  202. for(i = 0; i < CH_WIDTH; i++) {
  203. y = (int)(pixelv[i + CHA_OFFSET]);
  204. x = (int)(pixelv[i + CHB_OFFSET]);
  205. distrib[y][x] += 1;
  206. if(distrib[y][x] > max) max=distrib[y][x];
  207. }
  208. }
  209. df = fopen(filename,"w");
  210. printf("Writing %s\n",filename);
  211. fprintf(df,"P2\n#max %d\n",max);
  212. fprintf(df,"256 256\n255\n");
  213. for(y=0;y<256;y++)
  214. for(x=0;x<256;x++)
  215. fprintf(df, "%d\n", (int)((255.0 * (double)(distrib[y][x])) / (double)max));
  216. fclose(df);
  217. }
  218. extern int Calibrate(float **prow, int nrow, int offset);
  219. extern void Temperature(float **prow, int nrow, int ch, int offset);
  220. extern int Ngvi(float **prow, int nrow);
  221. extern void readfconf(char *file);
  222. extern int optind, opterr;
  223. extern char *optarg;
  224. int satnum = 4;
  225. static void usage(void) {
  226. fprintf(stderr, "Aptdec [options] recordings ...\n");
  227. fprintf(stderr, "Options:\n -i [r|a|b|c|t] Output image type\n r: Raw\n a: A channel\n b: B channel\n c: False color\n t: Temperature\n -d <dir> Image destination directory.\n -s [15|16|17|18|19] Satellite number\n -c <file> False color config file\n");
  228. exit(1);
  229. }
  230. int main(int argc, char **argv) {
  231. char pngfilename[1024];
  232. char name[1024];
  233. char pngdirname[1024] = "";
  234. char imgopt[20] = "ac";
  235. float *prow[3000];
  236. char *chid[] = { "?", "1", "2", "3A", "4", "5", "3B" };
  237. int nrow;
  238. int chA, chB;
  239. int c;
  240. printf("%s\n", version);
  241. opterr = 0;
  242. if(argc == 1){
  243. usage();
  244. }
  245. while ((c = getopt(argc, argv, "c:d:i:s:")) != EOF) {
  246. switch (c) {
  247. case 'd':
  248. strcpy(pngdirname, optarg);
  249. break;
  250. case 'c':
  251. readfconf(optarg);
  252. break;
  253. case 'i':
  254. strcpy(imgopt, optarg);
  255. break;
  256. case 's':
  257. satnum = atoi(optarg)-15;
  258. if (satnum < 0 || satnum > 4) {
  259. fprintf(stderr, "Invalid satellite number, must be in the range [15-19]\n");
  260. exit(1);
  261. }
  262. break;
  263. default:
  264. usage();
  265. }
  266. }
  267. for (nrow = 0; nrow < 3000; nrow++)
  268. prow[nrow] = NULL;
  269. for (; optind < argc; optind++) {
  270. chA = chB = 0;
  271. strcpy(pngfilename, argv[optind]);
  272. strcpy(name, basename(pngfilename));
  273. strtok(name, ".");
  274. if (pngdirname[0] == '\0') {
  275. strcpy(pngfilename, argv[optind]);
  276. strcpy(pngdirname, dirname(pngfilename));
  277. }
  278. /* open snd input */
  279. if (initsnd(argv[optind]))
  280. exit(1);
  281. /* main loop */
  282. printf("Decoding: %s \n", argv[optind]);
  283. for (nrow = 0; nrow < 3000; nrow++) {
  284. if (prow[nrow] == NULL)
  285. prow[nrow] = (float *) malloc(sizeof(float) * 2150);
  286. if (getpixelrow(prow[nrow]) == 0)
  287. break;
  288. printf("%d\r", nrow);
  289. fflush(stdout);
  290. }
  291. printf("\nDone\n");
  292. sf_close(inwav);
  293. /* raw image */
  294. if (strchr(imgopt, (int) 'r') != NULL) {
  295. sprintf(pngfilename, "%s/%s-r.png", pngdirname, name);
  296. ImageOut(pngfilename, "raw", prow, nrow, IMG_WIDTH, 0, NULL);
  297. }
  298. /* Channel A */
  299. if (((strchr(imgopt, (int) 'a') != NULL)
  300. || (strchr(imgopt, (int) 'c') != NULL)
  301. || (strchr(imgopt, (int) 'd') != NULL))) {
  302. chA = Calibrate(prow, nrow, CHA_OFFSET);
  303. if (chA >= 0 && strchr(imgopt, (int) 'a') != NULL) {
  304. sprintf(pngfilename, "%s/%s-%s.png", pngdirname, name, chid[chA]);
  305. ImageOut(pngfilename, chid[chA], prow, nrow, CH_WIDTH , CHA_OFFSET, NULL);
  306. }
  307. }
  308. /* Channel B */
  309. if ((strchr(imgopt, (int) 'b') != NULL)
  310. || (strchr(imgopt, (int) 'c') != NULL)
  311. || (strchr(imgopt, (int) 't') != NULL)
  312. || (strchr(imgopt, (int) 'd') != NULL)) {
  313. chB = Calibrate(prow, nrow, CHB_OFFSET);
  314. if (chB >= 0 && strchr(imgopt, (int) 'b') != NULL) {
  315. sprintf(pngfilename, "%s/%s-%s.png", pngdirname, name, chid[chB]);
  316. ImageOut(pngfilename, chid[chB], prow, nrow, CH_WIDTH , CHB_OFFSET ,NULL);
  317. }
  318. if (chB > 3) {
  319. Temperature(prow, nrow, chB, CHB_OFFSET);
  320. if (strchr(imgopt, (int) 't') != NULL) {
  321. sprintf(pngfilename, "%s/%s-t.png", pngdirname, name);
  322. ImageOut(pngfilename, "Temperature", prow, nrow, CH_WIDTH, CHB_OFFSET, (png_color*)TempPalette);
  323. }
  324. }
  325. }
  326. /* distribution */
  327. if (chA && chB && strchr(imgopt, (int) 'd') != NULL) {
  328. sprintf(pngfilename, "%s/%s-d.pnm", pngdirname, name);
  329. Distrib(pngfilename, prow, nrow);
  330. }
  331. /* color image */
  332. if (chA == 2 && chB == 4 && strchr(imgopt, (int) 'c') != NULL) {
  333. sprintf(pngfilename, "%s/%s-c.png", pngdirname, name);
  334. ImageRGBOut(pngfilename, prow, nrow);
  335. }
  336. /* GVI image */
  337. if (chA == 1 && chB == 2 && strchr(imgopt, (int) 'c') != NULL) {
  338. Ngvi(prow, nrow);
  339. sprintf(pngfilename, "%s/%s-c.png", pngdirname, name);
  340. ImageOut(pngfilename, "GVI", prow, nrow, CH_WIDTH, CHB_OFFSET, (png_color*)GviPalette);
  341. }
  342. }
  343. exit(0);
  344. }