Guest User

HDMI Morse code transmission using an animated GIF

a guest
Jan 15th, 2024
286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.43 KB | Source Code | 0 0
  1. /* Compile with: gcc -std=c11 -o gif gif.c -lgd */
  2.  
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdbool.h>
  6. #include <err.h>
  7. #include <gd.h>
  8.  
  9. const char * const morse_alpha[] = {
  10.     ".-",   // A
  11.     "-...", // B
  12.     "-.-.", // C
  13.     "-..",  // D
  14.     ".",    // E
  15.     "..-.", // F
  16.     "--.",  // G
  17.     "....", // H
  18.     "..",   // I
  19.     ".---", // J
  20.     "-.-",  // K
  21.     ".-..", // L
  22.     "--",   // M
  23.     "-.",   // N
  24.     "---",  // O
  25.     ".--.", // P
  26.     "--.-", // Q
  27.     ".-.",  // R
  28.     "...",  // S
  29.     "-",    // T
  30.     "..-",  // U
  31.     "...-", // V
  32.     ".--",  // W
  33.     "-..-", // X
  34.     "-.--", // Y
  35.     "--..", // Z
  36.     "    " // space
  37. };
  38.  
  39. const char * const morse_digit[] = {
  40.     "-----", // 0
  41.     ".----", // 1
  42.     "..---", // 2
  43.     "...--", // 3
  44.     "....-", // 4
  45.     ".....", // 5
  46.     "-....", // 6
  47.     "--...", // 7
  48.     "---..", // 8
  49.     "----.", // 9
  50. };
  51.  
  52. int morse_encode(int *data, int data_len, const char *string)
  53. {
  54.     int data_idx = 0;
  55.  
  56.     void append_data(int value)
  57.     {
  58.     if(data_idx < data_len)
  59.         data[data_idx++] = value;
  60.     }
  61.    
  62.     char c;
  63.     while(c = *string++) {
  64.     int idx;
  65.     char **table = NULL;
  66.    
  67.     if(c >= 'A' && c <= 'Z') {
  68.         table = morse_alpha;
  69.         idx = c - 'A';
  70.     } else if(c >= 'a' && c <= 'z') {
  71.         table = morse_alpha;
  72.         idx = c - 'a';
  73.     } else if(c >= '0' && c <= '9') {
  74.         table = morse_digit;
  75.         idx = c - '0';
  76.     } else  if(c == ' ') {
  77.         table = morse_alpha;
  78.         idx = 26;
  79.     } else {
  80.         abort();
  81.     }
  82.     if(table == NULL)
  83.         continue;
  84.  
  85.     const char *morse = table[idx];
  86.  
  87.     printf("%c -> %s\n", c, table[idx]);
  88.    
  89.     for(int i = 0; i < strlen(morse); i++) {
  90.         char m = morse[i];
  91.         switch(m) {
  92.         case '.':
  93.         append_data(1);
  94.         break;
  95.         case '-':
  96.         append_data(1);
  97.         append_data(1);
  98.         append_data(1);
  99.         break;
  100.         case ' ':
  101.         append_data(0);
  102.         break;
  103.         }
  104.  
  105.         append_data(0);
  106.     }
  107.  
  108.     // space between letters is three units
  109.     append_data(0);
  110.     append_data(0);
  111.     }
  112.        
  113.     return data_idx;
  114. }
  115.  
  116.  
  117. int main(int argc, char **argv)
  118. {
  119.     gdImagePtr im[2];
  120.     FILE *out;
  121.  
  122.     int num_frames = 3;
  123.    
  124.     for(int i = 0; i < num_frames; i++) {
  125.     gdImagePtr img;
  126.     img = gdImageCreate(8, 8);
  127.  
  128.     int fg_val = 0x7f;
  129.     int bg_val = 0x80;
  130.  
  131.     #if 0
  132.     fg_val = 0xff;
  133.     bg_val = 0x00;
  134.     #endif
  135.  
  136.     #if 0
  137.     int palette[256];
  138.    
  139.     for(int c = 0; c < 256; c++) {
  140.         palette[c] = gdImageColorAllocate(img, c, c, c);
  141.     }
  142.     #endif
  143.    
  144.     int fg = gdImageColorAllocate(img, fg_val, fg_val, fg_val);
  145.     int bg = gdImageColorAllocate(img, bg_val, bg_val, bg_val);
  146.    
  147.     for(int y = 0; y < gdImageSY(img); y++) {
  148.         for(int x = 0; x < gdImageSX(img); x++) {
  149.         bool tx_on = false;
  150.        
  151.         if(i >= 1) {
  152.             if(1) { // y < (gdImageSY(img) / 2) ) {
  153.             if((x >> 0) & 1)
  154.                 tx_on = !tx_on;
  155.             if((y >> 0) & 1)
  156.                 tx_on = !tx_on;
  157.             } else {
  158.             if((x >> 1) & 1)
  159.                 tx_on = !tx_on;
  160.             if((y >> 1) & 1)
  161.                 tx_on = !tx_on;
  162.             }
  163.         } else {
  164.             if((x >> 1) & 1)
  165.             tx_on = !tx_on;
  166.             if((y >> 1) & 1)
  167.             tx_on = !tx_on;
  168.             tx_on = false;
  169.         }
  170.  
  171.         if(i == 2) {
  172.             if(y > (gdImageSY(img) / 2))
  173.             tx_on = false;
  174.         }
  175.         gdImageSetPixel(img, x, y, tx_on ? fg : bg);
  176.         }
  177.     }
  178.    
  179.     im[i] = img;
  180.     }
  181.  
  182.     out = fopen("out.gif", "w");
  183.     if(out == NULL)
  184.     err(1, "unable to open output file");
  185.  
  186.     int morse_array[16384];
  187.     int len;
  188.     len = morse_encode(morse_array, 16384, "HIDDEN MORSE TX IN WEB PAGE WTF  ");
  189.     for(int i = 0; i < len; i++) {
  190.     printf("%d", morse_array[i]);
  191.     }
  192.     printf("\n");
  193.    
  194.     gdImageGifAnimBegin(im[2], out, 1, 0);
  195.  
  196.     #if 0
  197.     gdImageGifAnimAdd(im[2], out, 0, 0, 0, 0,
  198.               gdDisposalRestorePrevious, NULL);
  199.     #endif
  200.  
  201.     gdImagePtr prev = im[0];
  202.  
  203.     srand(1);
  204.     int prev_data = morse_array[0];
  205.     int im_prev_data = -1;
  206.     int pos = 1;
  207.     int num_periods = 0;
  208.     while(pos <= len) {
  209.     int data;
  210.     if(pos < len)
  211.         data = morse_array[pos];
  212.     else
  213.         data = -1;
  214.     num_periods++;
  215.  
  216.     if(data != prev_data) {
  217.         gdImageGifAnimAdd(im[prev_data], out, 0, 0, 0, num_periods * 10,
  218.                   gdDisposalNone, NULL);
  219.         num_periods = 0;
  220.     }
  221.  
  222.     prev_data = data;
  223.     pos++;
  224.     }
  225.  
  226.     #if 0
  227.     for(int i = 0; i < len; i++) {
  228.     int idx = morse_array[i] & 1;
  229.     gdImageGifAnimAdd(im[idx], out, 0, 0, 0, 10, gdDisposalRestorePrevious, NULL);
  230.     }
  231.     #endif
  232.     gdImageGifAnimEnd(out);
  233.    
  234.     fclose(out);
  235.    
  236.     return 0;
  237. }
  238.  
Advertisement
Add Comment
Please, Sign In to add comment