int main(int argc, char *argv[]) { int c, i; FILE *fin = stdin; FILE *fout = stdout; char encode = -1; int droptest = 0; char callsign[7]; uint8_t image_id = 0; ssdv_t ssdv; uint8_t pkt[SSDV_PKT_SIZE], b[128], *jpeg; size_t jpeg_length; callsign[0] = '\0'; opterr = 0; while((c = getopt(argc, argv, "edc:i:t:")) != -1) { switch(c) { case 'e': encode = 1; break; case 'd': encode = 0; break; case 'c': if(strlen(optarg) > 6) fprintf(stderr, "Warning: callsign is longer than 6 characters.\n"); strncpy(callsign, optarg, 7); break; case 'i': image_id = atoi(optarg); break; case 't': droptest = atoi(optarg); break; case '?': exit_usage(); } } c = argc - optind; if(c > 2) exit_usage(); for(i = 0; i < c; i++) { if(!strcmp(argv[optind + i], "-")) continue; switch(i) { case 0: fin = fopen(argv[optind + i], "rb"); if(!fin) { fprintf(stderr, "Error opening '%s' for input:\n", argv[optind + i]); perror("fopen"); return(-1); } break; case 1: fout = fopen(argv[optind + i], "wb"); if(!fout) { fprintf(stderr, "Error opening '%s' for output:\n", argv[optind + i]); perror("fopen"); return(-1); } break; } } switch(encode) { case 0: /* Decode */ if(droptest > 0) fprintf(stderr, "*** NOTE: Drop test enabled: %i ***\n", droptest); ssdv_dec_init(&ssdv); jpeg_length = 1024 * 1024 * 4; jpeg = malloc(jpeg_length); ssdv_dec_set_buffer(&ssdv, jpeg, jpeg_length); i = 0; while(fread(pkt, 1, SSDV_PKT_SIZE, fin) > 0) { /* Drop % of packets */ if(droptest && (rand() / (RAND_MAX / 100) < droptest)) continue; /* Test the packet is valid */ if(ssdv_dec_is_packet(pkt, NULL) != 0) continue; /* Feed it to the decoder */ ssdv_dec_feed(&ssdv, pkt); i++; } ssdv_dec_get_jpeg(&ssdv, &jpeg, &jpeg_length); fwrite(jpeg, 1, jpeg_length, fout); free(jpeg); fprintf(stderr, "Read %i packets\n", i); break; case 1: /* Encode */ ssdv_enc_init(&ssdv, callsign, image_id); ssdv_enc_set_buffer(&ssdv, pkt); i = 0; while(1) { while((c = ssdv_enc_get_packet(&ssdv)) == SSDV_FEED_ME) { size_t r = fread(b, 1, 128, fin); if(r <= 0) { fprintf(stderr, "Premature end of file\n"); break; } ssdv_enc_feed(&ssdv, b, r); } if(c == SSDV_EOI) { fprintf(stderr, "ssdv_enc_get_packet said EOI\n"); break; } else if(c != SSDV_OK) { fprintf(stderr, "ssdv_enc_get_packet failed: %i\n", c); return(-1); } fwrite(pkt, 1, SSDV_PKT_SIZE, fout); i++; } fprintf(stderr, "Wrote %i packets\n", i); break; default: fprintf(stderr, "No mode specified.\n"); break; } if(fin != stdin) fclose(fin); if(fout != stdout) fclose(fout); return(0); }
int main(int argc, char *argv[]) { struct termios serial; int c, i; FILE *fin = stdin; FILE *fout = stdout; int fd; int wcount; char encode = -1; int droptest = 0; char callsign[7]; uint8_t image_id = 0; ssdv_t ssdv; uint8_t pkt[SSDV_PKT_SIZE], b[128], *jpeg; size_t jpeg_length; callsign[0] = '\0'; opterr = 0; while((c = getopt(argc, argv, "edc:i:t:")) != -1) { switch(c) { case 'e': encode = 1; break; case 'd': encode = 0; break; case 'c': if(strlen(optarg) > 6) fprintf(stderr, "Warning: callsign is longer than 6 characters.\n"); strncpy(callsign, optarg, 7); break; case 'i': image_id = atoi(optarg); break; case 't': droptest = atoi(optarg); break; case '?': exit_usage(); } } c = argc - optind; if(c > 2) exit_usage(); for(i = 0; i < c; i++) { if(!strcmp(argv[optind + i], "-")) continue; switch(i) { case 0: fin = fopen(argv[optind + i], "rb"); if(!fin) { fprintf(stderr, "Error opening '%s' for input:\n", argv[optind + i]); perror("fopen"); return(-1); } break; } } switch(encode) { case 0: /* Decode */ if(droptest > 0) fprintf(stderr, "*** NOTE: Drop test enabled: %i ***\n", droptest); ssdv_dec_init(&ssdv); jpeg_length = 1024 * 1024 * 4; jpeg = malloc(jpeg_length); ssdv_dec_set_buffer(&ssdv, jpeg, jpeg_length); i = 0; while(fread(pkt, 1, SSDV_PKT_SIZE, fin) > 0) { /* Drop % of packets */ if(droptest && (rand() / (RAND_MAX / 100) < droptest)) continue; /* Test the packet is valid */ if(ssdv_dec_is_packet(pkt, NULL) != 0) continue; /* Feed it to the decoder */ ssdv_dec_feed(&ssdv, pkt); i++; } ssdv_dec_get_jpeg(&ssdv, &jpeg, &jpeg_length); fwrite(jpeg, 1, jpeg_length, fout); free(jpeg); fprintf(stderr, "Read %i packets\n", i); break; case 1: /* Encode */ ssdv_enc_init(&ssdv, callsign, image_id); ssdv_enc_set_buffer(&ssdv, pkt); i = 0; while(1) { fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror("Failed to open Serial Port"); return -1; } if (tcgetattr(fd, &serial) < 0) { perror("Failed to read Serial Port Configuration"); return -1; } // Set up Serial Configuration serial.c_iflag = 0; serial.c_oflag = 0; serial.c_lflag = 0; serial.c_cflag = 0; serial.c_cc[VMIN] = 0; serial.c_cc[VTIME] = 0; serial.c_cflag = B600 | CS8 | CREAD; tcsetattr(fd, TCSANOW, &serial); // Apply Serial configuration while((c = ssdv_enc_get_packet(&ssdv)) == SSDV_FEED_ME) { size_t r = fread(b, 1, 128, fin); if(r <= 0) { fprintf(stderr, "Premature end of file\n"); break; } ssdv_enc_feed(&ssdv, b, r); } if(c == SSDV_EOI) { fprintf(stderr, "ssdv_enc_get_packet said EOI\n"); break; } else if(c != SSDV_OK) { fprintf(stderr, "ssdv_enc_get_packet failed: %i\n", c); return(-1); } wcount = write(fd, pkt, SSDV_PKT_SIZE); if (wcount < 0) { perror("Writing to Serial Port"); return -1; } close(fd); i++; } fprintf(stderr, "Wrote %i packets\n", i); break; default: fprintf(stderr, "No mode specified.\n"); break; } if(fin != stdin) fclose(fin); if(fout != stdout) fclose(fout); close(fd); return(0); }