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.
 
 
 
 
 

408 lines
11 KiB

  1. /*
  2. * Atpdec
  3. * Copyright (c) 2004 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 <stdio.h>
  23. #ifdef WIN32
  24. #include "w32util.h"
  25. #else
  26. #include <libgen.h>
  27. #endif
  28. #include <string.h>
  29. #include <sndfile.h>
  30. #include <png.h>
  31. #include "version.h"
  32. extern int getpixelrow(float *pixelv);
  33. #define SYNC_WIDTH 39
  34. #define SPC_WIDTH 47
  35. #define TELE_WIDTH 45
  36. #define CH_WIDTH 909
  37. #define CH_OFFSET (SYNC_WIDTH+SPC_WIDTH+CH_WIDTH+TELE_WIDTH)
  38. #define IMG_WIDTH 2080
  39. static SNDFILE *inwav;
  40. static int initsnd(char *filename)
  41. {
  42. SF_INFO infwav;
  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\n", filename);
  48. return (1);
  49. }
  50. if (infwav.samplerate != 11025) {
  51. fprintf(stderr, "Bad Input File sample rate: %d. Must be 11025\n",
  52. infwav.samplerate);
  53. return (1);
  54. }
  55. if (infwav.channels != 1) {
  56. fprintf(stderr, "Too many channels in input file : %d\n",
  57. infwav.channels);
  58. return (1);
  59. }
  60. return (0);
  61. }
  62. int getsample(float *sample, int nb)
  63. {
  64. return (sf_read_float(inwav, sample, nb));
  65. }
  66. static png_text text_ptr[] = {
  67. {PNG_TEXT_COMPRESSION_NONE, "Software", version, sizeof(version)}
  68. ,
  69. {PNG_TEXT_COMPRESSION_NONE, "Channel", NULL, 0}
  70. ,
  71. {PNG_TEXT_COMPRESSION_NONE, "Description", "NOAA POES satellite Image",
  72. 25}
  73. };
  74. static int
  75. ImageOut(char *filename, char *chid, float **prow, int nrow,
  76. int width, int offset)
  77. {
  78. FILE *pngfile;
  79. png_infop info_ptr;
  80. png_structp png_ptr;
  81. int n;
  82. /* init png lib */
  83. png_ptr =
  84. png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  85. if (!png_ptr) {
  86. fprintf(stderr, "could not open create png_ptr\n");
  87. return (1);
  88. }
  89. info_ptr = png_create_info_struct(png_ptr);
  90. if (!info_ptr) {
  91. png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
  92. fprintf(stderr, "could not open create info_ptr\n");
  93. return (1);
  94. }
  95. png_set_IHDR(png_ptr, info_ptr, width, nrow,
  96. 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
  97. PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  98. text_ptr[1].text = chid;
  99. text_ptr[1].text_length = strlen(chid);
  100. png_set_text(png_ptr, info_ptr, text_ptr, 3);
  101. png_set_pHYs(png_ptr, info_ptr, 4000, 4000, PNG_RESOLUTION_METER);
  102. printf("Writing %s ... ", filename);
  103. fflush(stdout);
  104. pngfile = fopen(filename, "wb");
  105. if (pngfile == NULL) {
  106. fprintf(stderr, "could not open %s\n", filename);
  107. return (1);
  108. }
  109. png_init_io(png_ptr, pngfile);
  110. png_write_info(png_ptr, info_ptr);
  111. for (n = 0; n < nrow; n++) {
  112. float *pixelv;
  113. png_byte pixel[2*IMG_WIDTH];
  114. int i;
  115. pixelv = prow[n];
  116. for (i = 0; i < width; i++) {
  117. pixel[i] = pixelv[i + offset];
  118. }
  119. png_write_row(png_ptr, pixel);
  120. }
  121. png_write_end(png_ptr, info_ptr);
  122. fclose(pngfile);
  123. printf("Done\n");
  124. png_destroy_write_struct(&png_ptr, &info_ptr);
  125. return (0);
  126. }
  127. int ImageColorOut(char *filename, float **prow, int nrow)
  128. {
  129. FILE *pngfile;
  130. png_infop info_ptr;
  131. png_structp png_ptr;
  132. int n;
  133. float *pixelc, *pixeln;
  134. extern void falsecolor(double v, double t, float *r, float *g,
  135. float *b);
  136. /* init png lib */
  137. png_ptr =
  138. png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  139. if (!png_ptr) {
  140. fprintf(stderr, "could not open create png_ptr\n");
  141. return (1);
  142. }
  143. info_ptr = png_create_info_struct(png_ptr);
  144. if (!info_ptr) {
  145. png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
  146. fprintf(stderr, "could not open create info_ptr\n");
  147. return (1);
  148. }
  149. png_set_IHDR(png_ptr, info_ptr, 2 * (CH_WIDTH - 1), 2 * (nrow - 1),
  150. 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
  151. PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  152. png_set_pHYs(png_ptr, info_ptr, 2000, 2000, PNG_RESOLUTION_METER);
  153. text_ptr[1].text = "False Colors";
  154. text_ptr[1].text_length = strlen(text_ptr[1].text);
  155. png_set_text(png_ptr, info_ptr, text_ptr, 3);
  156. printf("Computing False colors & writing : %s ...", filename);
  157. fflush(stdout);
  158. pngfile = fopen(filename, "wb");
  159. if (pngfile == NULL) {
  160. fprintf(stderr, "could not open %s\n", filename);
  161. return (1);
  162. }
  163. png_init_io(png_ptr, pngfile);
  164. png_write_info(png_ptr, info_ptr);
  165. for (n = 0; n < nrow - 1; n++) {
  166. png_color pix[2 * CH_WIDTH];
  167. float r, g, b;
  168. float v, vs, t, ts;
  169. int i;
  170. pixelc = prow[n];
  171. pixeln = prow[n + 1];
  172. v = (pixelc[SYNC_WIDTH + SPC_WIDTH] +
  173. pixeln[SYNC_WIDTH + SPC_WIDTH]) / 2.0;
  174. for (i = 0; i < CH_WIDTH - 1; i++) {
  175. t = pixelc[i + SYNC_WIDTH + SPC_WIDTH + CH_OFFSET];
  176. falsecolor(v, t, &r, &g, &b);
  177. pix[2 * i].red = 255.0 * r;
  178. pix[2 * i].green = 255.0 * g;
  179. pix[2 * i].blue = 255.0 * b;
  180. vs = (pixelc[i + 1 + SYNC_WIDTH + SPC_WIDTH] +
  181. pixeln[i + 1 + SYNC_WIDTH + SPC_WIDTH]) / 2.0;
  182. v = (v + vs) / 2.0;
  183. t = (pixelc[i + SYNC_WIDTH + SPC_WIDTH + CH_OFFSET] +
  184. pixelc[i + 1 + SYNC_WIDTH + SPC_WIDTH + CH_OFFSET]) / 2.0;
  185. falsecolor(v, t, &r, &g, &b);
  186. pix[2 * i + 1].red = 255.0 * r;
  187. pix[2 * i + 1].green = 255.0 * g;
  188. pix[2 * i + 1].blue = 255.0 * b;
  189. v = vs;
  190. }
  191. png_write_row(png_ptr, (png_bytep) pix);
  192. t = (pixelc[SYNC_WIDTH + SPC_WIDTH + CH_OFFSET] +
  193. pixeln[SYNC_WIDTH + SPC_WIDTH + CH_OFFSET]) / 2.0;
  194. for (i = 0; i < CH_WIDTH - 1; i++) {
  195. v = pixeln[i + SYNC_WIDTH + SPC_WIDTH];
  196. falsecolor(v, t, &r, &g, &b);
  197. pix[2 * i].red = 255.0 * r;
  198. pix[2 * i].green = 255.0 * g;
  199. pix[2 * i].blue = 255.0 * b;
  200. v = (pixeln[i + SYNC_WIDTH + SPC_WIDTH] +
  201. pixeln[i + 1 + SYNC_WIDTH + SPC_WIDTH]) / 2.0;
  202. ts = (pixelc[i + SYNC_WIDTH + SPC_WIDTH + CH_OFFSET] +
  203. pixeln[i + 1 + SYNC_WIDTH + SPC_WIDTH +
  204. CH_OFFSET]) / 2.0;
  205. t = (t + ts) / 2.0;
  206. falsecolor(v, t, &r, &g, &b);
  207. pix[2 * i + 1].red = 255.0 * r;
  208. pix[2 * i + 1].green = 255.0 * g;
  209. pix[2 * i + 1].blue = 255.0 * b;
  210. t = ts;
  211. }
  212. png_write_row(png_ptr, (png_bytep) pix);
  213. }
  214. png_write_end(png_ptr, info_ptr);
  215. fclose(pngfile);
  216. printf("Done\n");
  217. png_destroy_write_struct(&png_ptr, &info_ptr);
  218. return (0);
  219. }
  220. extern int Calibrate(float **prow, int nrow, int offset);
  221. extern void Temperature(float **prow, int nrow, int ch, int offset);
  222. extern void readfconf(char *file);
  223. extern int optind, opterr;
  224. extern char *optarg;
  225. int satnum = 1;
  226. static void usage(void)
  227. {
  228. fprintf(stderr, "atpdec [options] soundfiles ...\n");
  229. fprintf(stderr,
  230. "options:\n-d <dir>\tDestination directory\n-i [a|b|c|t]\tOutput image type\n\t\t\tr: Raw\n\t\t\ta: A chan.\n\t\t\tb: B chan.\n\t\t\tc: False color\n\t\t\tt: Temperature\n-c <file>\tFalse color config file\n-s [0|1]\tSatellite id (for temperature and false color generation)\n\t\t\t0:NOAA15\n\t\t\t1:NOAA17\n");
  231. exit(1);
  232. }
  233. int main(int argc, char **argv)
  234. {
  235. char pngfilename[1024];
  236. char name[1024];
  237. char pngdirname[1024] = "";
  238. char imgopt[20] = "ac";
  239. float *prow[3000];
  240. char *chid[6] = { "1", "2", "3A", "4", "5", "3B" };
  241. int nrow;
  242. int ch;
  243. int c;
  244. printf("%s\n", version);
  245. opterr = 0;
  246. while ((c = getopt(argc, argv, "c:d:i:s:")) != EOF) {
  247. switch (c) {
  248. case 'd':
  249. strcpy(pngdirname, optarg);
  250. break;
  251. case 'c':
  252. readfconf(optarg);
  253. break;
  254. case 'i':
  255. strcpy(imgopt, optarg);
  256. break;
  257. case 's':
  258. satnum = atoi(optarg);
  259. if (satnum < 0 || satnum > 1) {
  260. fprintf(stderr, "invalid satellite\n");
  261. exit(1);
  262. }
  263. break;
  264. default:
  265. usage();
  266. }
  267. }
  268. for (nrow = 0; nrow < 3000; nrow++)
  269. prow[nrow] = NULL;
  270. for (; optind < argc; optind++) {
  271. int a = 0, b = 0;
  272. strcpy(pngfilename, argv[optind]);
  273. strcpy(name, basename(pngfilename));
  274. strtok(name, ".");
  275. if (pngdirname[0] == '\0') {
  276. strcpy(pngfilename, argv[optind]);
  277. strcpy(pngdirname, dirname(pngfilename));
  278. }
  279. /* open snd input */
  280. if (initsnd(argv[optind]))
  281. exit(1);
  282. /* main loop */
  283. printf("Decoding: %s \n", argv[optind]);
  284. for (nrow = 0; nrow < 3000; nrow++) {
  285. if (prow[nrow] == NULL)
  286. prow[nrow] = (float *) malloc(sizeof(float) * 2150);
  287. if (getpixelrow(prow[nrow]) == 0)
  288. break;
  289. printf("%d\r", nrow);
  290. fflush(stdout);
  291. }
  292. printf("\nDone\n");
  293. sf_close(inwav);
  294. /* raw image */
  295. if (strchr(imgopt, (int) 'r') != NULL) {
  296. sprintf(pngfilename, "%s/%s-r.png", pngdirname, name);
  297. ImageOut(pngfilename, "raw", prow, nrow, IMG_WIDTH, 0);
  298. }
  299. /* Channel A */
  300. if (((strchr(imgopt, (int) 'a') != NULL)
  301. || (strchr(imgopt, (int) 'c') != NULL)
  302. || (strchr(imgopt, (int) 'd') != NULL))) {
  303. ch = Calibrate(prow, nrow, SYNC_WIDTH);
  304. if (ch >= 0) {
  305. if (strchr(imgopt, (int) 'a') != NULL) {
  306. sprintf(pngfilename, "%s/%s-%s.png", pngdirname, name,
  307. chid[ch]);
  308. ImageOut(pngfilename, chid[ch], prow, nrow,
  309. SPC_WIDTH + CH_WIDTH + TELE_WIDTH,
  310. SYNC_WIDTH);
  311. }
  312. }
  313. if (ch < 2)
  314. a = 1;
  315. }
  316. /* Channel B */
  317. if ((strchr(imgopt, (int) 'b') != NULL)
  318. || (strchr(imgopt, (int) 'c') != NULL)
  319. || (strchr(imgopt, (int) 't') != NULL)
  320. || (strchr(imgopt, (int) 'd') != NULL)) {
  321. ch = Calibrate(prow, nrow, CH_OFFSET + SYNC_WIDTH);
  322. if (ch >= 0) {
  323. if (strchr(imgopt, (int) 'b') != NULL) {
  324. sprintf(pngfilename, "%s/%s-%s.png", pngdirname, name,
  325. chid[ch]);
  326. ImageOut(pngfilename, chid[ch], prow, nrow,
  327. SPC_WIDTH + CH_WIDTH + TELE_WIDTH,
  328. CH_OFFSET + SYNC_WIDTH);
  329. }
  330. }
  331. if (ch > 2) {
  332. b = 1;
  333. Temperature(prow, nrow, ch, CH_OFFSET + SYNC_WIDTH);
  334. if (strchr(imgopt, (int) 't') != NULL) {
  335. sprintf(pngfilename, "%s/%s-t.png", pngdirname, name);
  336. ImageOut(pngfilename, "Temperature", prow, nrow,
  337. CH_WIDTH, CH_OFFSET + SYNC_WIDTH + SPC_WIDTH);
  338. }
  339. }
  340. }
  341. /* distribution */
  342. if (a && b && strchr(imgopt, (int) 'd') != NULL) {
  343. sprintf(pngfilename, "%s/%s-d.pnm", pngdirname, name);
  344. }
  345. /* color image */
  346. if (a && b && strchr(imgopt, (int) 'c') != NULL) {
  347. sprintf(pngfilename, "%s/%s-c.png", pngdirname, name);
  348. ImageColorOut(pngfilename, prow, nrow);
  349. }
  350. }
  351. exit(0);
  352. }