home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / scaleos2.zip / scale.c < prev    next >
C/C++ Source or Header  |  1997-12-27  |  7KB  |  196 lines

  1. /* SCALE.C  v1.0
  2.    scale TGA and interpolate values
  3.    code last modified by U. A. Mueller, 27 Dec. 97.*/
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <mem.h>
  7. #include <string.h>
  8.  
  9. #define prog_version "1.0"
  10. #define prog_date    "27. Dec 1997"
  11. #define size_fact    3*sizeof(UI)
  12.  
  13. typedef struct Image_Line_Struct IMAGE_LINE;
  14. typedef float UI;
  15.  
  16. struct Image_Line_Struct
  17. {
  18.   UI red, green, blue;
  19. };
  20.  
  21. int main (int argc, char *argv[])
  22. {
  23.    FILE          *inf, *outf;
  24.    unsigned char InText[19];
  25.    unsigned int  width_1, width_2, height_1, height_2, old_width, old_height, new_width, new_height,
  26.                  x, y, i, j, new_x, factor;
  27.    UI            diff_blue, diff_green, diff_red, tmp_factor_col, tmp_blue, tmp_green, tmp_red;
  28.    IMAGE_LINE    *act_line, *sec_line, *out_line, *sec_out_line;
  29.  
  30.    fprintf (stderr, "Scale TGA files v%s by U. A. Mueller %s\n", prog_version, prog_date);
  31.  
  32.    if (argc < 4)
  33.    {
  34.       fprintf (stderr, "Usage: %s <infile> <outfile> <scale factor>\n", argv[0]);
  35.       exit (1);
  36.    }
  37.  
  38.    if (strcmp (argv[1], argv[2]) == 0)
  39.    {
  40.       fprintf (stderr, "Input and output file must be different\n");
  41.       exit (1);
  42.    }
  43.  
  44.    if ((inf = fopen (argv[1], "rb")) == NULL)
  45.    {
  46.       perror (argv[1]);
  47.       exit (1);
  48.    }
  49.  
  50.    if ((outf = fopen(argv[2], "wb")) == NULL)
  51.    {
  52.      fprintf (stderr, "can't open output file %s\n", argv[2]);
  53.      exit (1);
  54.    }
  55.  
  56.    factor = atoi (argv[3]);
  57.  
  58.    if (factor < 2)
  59.    {
  60.      fprintf (stderr, "factor must be at least 2\n");
  61.      exit (1);
  62.    }
  63.  
  64.    /* Read header and calculate new size */
  65.    fscanf  (inf, "%18c", InText);
  66.    width_1  = InText[12];
  67.    width_2  = InText[13];
  68.    height_1 = InText[14];
  69.    height_2 = InText[15];
  70.    old_width  = width_1  + (width_2  << 8);
  71.    old_height = height_1 + (height_2 << 8);
  72.    fprintf (stderr, "%s:\t%d x %d\n", argv[1], old_height, old_width);
  73.    fprintf (stderr, "Factor:\t%d\n", factor);
  74.    new_width  = old_width * factor;
  75.    new_height = old_height * factor;
  76.    fprintf (stderr, "%s:\t%d x %d\n", argv[2], new_height, new_width);
  77.  
  78.    /* Write TGA image header: y origin set to "First_Line", 24 bits/pixel (16 million colors) */
  79.    /* Bitmask, pertinent bit: top-down raster */
  80.    fprintf (outf, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  81.             (short)(new_width % 256), (short)(new_width / 256),
  82.             (short)(new_height % 256), (short)(new_height / 256), 24, 32);
  83.    act_line     = (IMAGE_LINE *)malloc ((size_t)(size_fact * old_width));
  84.    sec_line     = (IMAGE_LINE *)malloc ((size_t)(size_fact * old_width));
  85.    out_line     = (IMAGE_LINE *)malloc ((size_t)(size_fact * new_width));
  86.    sec_out_line = (IMAGE_LINE *)malloc ((size_t)(size_fact * new_width));
  87.  
  88.    /* Read first line */
  89.    for (x = 0; x < old_width; x++)
  90.    {
  91.      sec_line[x].blue  = getc(inf);
  92.      sec_line[x].green = getc(inf);
  93.      sec_line[x].red   = getc(inf);
  94.    }
  95.  
  96.    /* Read and process lines */
  97.    for (y = 0; y < old_height; y++)
  98.    {
  99.      for (x = 0, new_x = 0; x < old_width; x++)
  100.      {
  101.        /* write next point */
  102.        out_line[new_x].blue  = sec_line[x].blue;
  103.        out_line[new_x].green = sec_line[x].green;
  104.        out_line[new_x].red   = sec_line[x].red;
  105.        fprintf (outf, "%c%c%c", (char)out_line[new_x].blue, (char)out_line[new_x].green, (char)out_line[new_x].red);
  106.        new_x++;
  107.  
  108.        if (x == (old_width - 1))
  109.        { /* last point in row */
  110.          diff_blue  = tmp_blue  = (sec_line[x].blue  - out_line[new_x - 2].blue)  / factor;
  111.          diff_green = tmp_green = (sec_line[x].green - out_line[new_x - 2].green) / factor;
  112.          diff_red   = tmp_red   = (sec_line[x].red   - out_line[new_x - 2].red)   / factor;
  113.        }
  114.        else
  115.        {
  116.          diff_blue  = tmp_blue  = (sec_line[x + 1].blue  - sec_line[x].blue)  / factor;
  117.          diff_green = tmp_green = (sec_line[x + 1].green - sec_line[x].green) / factor;
  118.          diff_red   = tmp_red   = (sec_line[x + 1].red   - sec_line[x].red)   / factor;
  119.        }
  120.  
  121.        for (i = 1; i < factor; i++)
  122.        {
  123.          out_line[new_x].blue  = sec_line[x].blue  + tmp_blue;
  124.          out_line[new_x].green = sec_line[x].green + tmp_green;
  125.          out_line[new_x].red   = sec_line[x].red   + tmp_red;
  126.          fprintf (outf, "%c%c%c", (char)out_line[new_x].blue, (char)out_line[new_x].green, (char)out_line[new_x].red);
  127.          new_x++;
  128.          tmp_blue  += diff_blue;
  129.          tmp_green += diff_green;
  130.          tmp_red   += diff_red;
  131.        }
  132.  
  133.        /* read next point */
  134.        if (y < (old_height - 1))
  135.        {
  136.          act_line[x].blue  = getc(inf);
  137.          act_line[x].green = getc(inf);
  138.          act_line[x].red   = getc(inf);
  139.        }
  140.      }
  141.  
  142.      memcpy (sec_out_line, out_line, new_width * size_fact);
  143.  
  144.      for (i = 1; i < factor; i++)
  145.      {
  146.        tmp_factor_col = (UI)i / (UI)factor;
  147.  
  148.        for (x = 0, new_x = 0; x < old_width; x++)
  149.        {
  150.          out_line[new_x].blue  = sec_line[x].blue  + (act_line[x].blue  - sec_line[x].blue)  * tmp_factor_col;
  151.          out_line[new_x].green = sec_line[x].green + (act_line[x].green - sec_line[x].green) * tmp_factor_col;
  152.          out_line[new_x].red   = sec_line[x].red   + (act_line[x].red   - sec_line[x].red)   * tmp_factor_col;
  153.          fprintf (outf, "%c%c%c", (char)out_line[new_x].blue, (char)out_line[new_x].green, (char)out_line[new_x].red);
  154.          new_x++;
  155.  
  156.          if (x == (old_width - 1))
  157.          { /* last point in row */
  158.            tmp_blue  = (act_line[x].blue  - out_line[new_x - 2].blue)  / factor;
  159.            tmp_green = (act_line[x].green - out_line[new_x - 2].green) / factor;
  160.            tmp_red   = (act_line[x].red   - out_line[new_x - 2].red)   / factor;
  161.          }
  162.          else
  163.          {
  164.            tmp_blue  = (act_line[x + 1].blue  - act_line[x].blue)  / factor;
  165.            tmp_green = (act_line[x + 1].green - act_line[x].green) / factor;
  166.            tmp_red   = (act_line[x + 1].red   - act_line[x].red)   / factor;
  167.          }
  168.  
  169.          diff_blue  = act_line[x].blue  + tmp_blue;
  170.          diff_green = act_line[x].green + tmp_green;
  171.          diff_red   = act_line[x].red   + tmp_red;
  172.  
  173.          for (j = 1; j < factor; j++)
  174.          {
  175.            out_line[new_x].blue  = sec_out_line[new_x].blue  + (diff_blue  - sec_out_line[new_x].blue)  * tmp_factor_col;
  176.            out_line[new_x].green = sec_out_line[new_x].green + (diff_green - sec_out_line[new_x].green) * tmp_factor_col;
  177.            out_line[new_x].red   = sec_out_line[new_x].red   + (diff_red   - sec_out_line[new_x].red)   * tmp_factor_col;
  178.            fprintf (outf, "%c%c%c", (char)out_line[new_x].blue, (char)out_line[new_x].green, (char)out_line[new_x].red);
  179.            diff_blue  += tmp_blue;
  180.            diff_green += tmp_green;
  181.            diff_red   += tmp_red;
  182.            new_x++;
  183.          }
  184.        }
  185.      }
  186.  
  187.      memcpy (sec_line, act_line, old_width * size_fact);
  188.    }
  189.  
  190.    fclose (inf);
  191.    fclose (outf);
  192.    free (inf);
  193.    free (outf);
  194.    return (0);
  195. }
  196.