home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Multimed / Multimed.zip / kdc_dc2.zip / kdc2bmp.c < prev    next >
C/C++ Source or Header  |  1998-02-03  |  12KB  |  349 lines

  1. /*
  2.  * kdc2bmp.c - Converts an uncompressed DC-120 .kdc file to a .bmp file
  3.  *
  4.  * The 848x976 CCD data is converted to 1272x976.
  5.  *
  6.  * The CCD data starts at offset 15680 in the .kdc file, and
  7.  * is stored one row at a time.  Each row is rotated by a
  8.  * pseudo-random number (in kdcoff below).
  9.  *
  10.  * Once the data is unrotated it is laid out in a Bayer pattern:
  11.  *
  12.  *   GRGRGR (R is red, G is green, B is blue)
  13.  *   BGBGBG
  14.  *   GRGRGR
  15.  *   BGBGBG
  16.  *
  17.  * The RGB data is then linearly interpolated, and then stretched
  18.  * by a factor of 1.5 in the horizontal direction.  This results
  19.  * in a 1272x976 image, which has an aspect ratio of 1.3.
  20.  *
  21.  * Author  : Ed Hamrick
  22.  * Date    : October 24, 1997
  23.  * See also: http://www.hamrick.com/
  24.  */
  25.  
  26. /*
  27.  * Further modifications by Stephane Charette, charette@writeme.com
  28.  * 1998Feb01
  29.  * compiled for OS/2 and uploaded to the internet as freeware, SC, 1998Feb01
  30.  */
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35.  
  36. /*
  37.  * Data for bmp header (24 bits per pixel, 1272x976)
  38.  */
  39.  
  40. static unsigned char bmphead[] = {
  41.   0x42, 0x4D, 0x36, 0x24, 0x00, 0x00, 0x00, 0x00,
  42.   0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
  43.   0x00, 0x00, 0xF8, 0x04, 0x00, 0x00, 0xD0, 0x03,
  44.   0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
  45.   0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
  46.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  47.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  48. };
  49.  
  50. /*
  51.  * Gamma correction table for gamma = 1.7
  52.  */
  53.  
  54. static unsigned char gamma[] = {
  55.     0, 10, 15, 19, 22, 25, 28, 31, 33, 36, 38, 40, 42, 44, 46, 48,
  56.    50, 52, 54, 55, 57, 59, 60, 62, 64, 65, 67, 68, 70, 71, 72, 74,
  57.    75, 77, 78, 79, 81, 82, 83, 84, 86, 87, 88, 89, 91, 92, 93, 94,
  58.    95, 97, 98, 99,100,101,102,103,105,106,107,108,109,110,111,112,
  59.   113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
  60.   129,130,131,132,133,134,135,135,136,137,138,139,140,141,142,143,
  61.   144,144,145,146,147,148,149,150,150,151,152,153,154,155,156,156,
  62.   157,158,159,160,160,161,162,163,164,164,165,166,167,168,168,169,
  63.   170,171,172,172,173,174,175,175,176,177,178,178,179,180,181,181,
  64.   182,183,184,184,185,186,187,187,188,189,190,190,191,192,192,193,
  65.   194,195,195,196,197,197,198,199,199,200,201,202,202,203,204,204,
  66.   205,206,206,207,208,208,209,210,210,211,212,212,213,214,214,215,
  67.   216,216,217,218,218,219,220,220,221,222,222,223,224,224,225,226,
  68.   226,227,227,228,229,229,230,231,231,232,233,233,234,234,235,236,
  69.   236,237,238,238,239,239,240,241,241,242,242,243,244,244,245,245,
  70.   246,247,247,248,248,249,250,250,251,251,252,253,253,254,254,255
  71. };
  72.  
  73. /*
  74.  * Data for decoding uncompressed .kdc files.  Kodak has gone
  75.  * to a great deal of trouble to make it hard to reverse-engineer
  76.  * this table, but I was able to compute it by calculating the
  77.  * offset at which scan lines were correlated.  Ed Hamrick, 10/24/97
  78.  */
  79.  
  80. static short int kdcoff[] = {
  81.     0,828,798,488,648,748,698,  8,448,668,598,376,248,588,498,744,
  82.    48,508,398,264,696,428,298,632,496,348,198,152,296,268, 98,520,
  83.    96,188,846, 40,744,108,746,408,544, 28,646,776,344,796,546,296,
  84.   144,716,446,664,792,636,346,184,592,556,246,552,392,476,146, 72,
  85.   192,396, 46,440,840,316,794,808,640,236,694,328,440,156,594,696,
  86.   240, 76,494,216, 40,844,394,584,688,764,294,104,488,684,194,472,
  87.   288,604, 94,840, 88,524,842,360,736,444,742,728,536,364,642,248,
  88.   336,284,542,616,136,204,442,136,784,124,342,504,584, 44,242, 24,
  89.   384,812,142,392,184,732, 42,760,832,652,790,280,632,572,690,648,
  90.   432,492,590,168,232,412,490,536, 32,332,390, 56,680,252,290,424,
  91.   480,172,190,792,280, 92, 90,312, 80, 12,838,680,728,780,738,200,
  92.   528,700,638,568,328,620,538, 88,128,540,438,456,776,460,338,824,
  93.   576,380,238,344,376,300,138,712,176,220, 38,232,824,140,786,600,
  94.   624, 60,686,120,424,828,586,488,224,748,486,  8, 24,668,386,376,
  95.   672,588,286,744,472,508,186,264,272,428, 86,632, 72,348,834,152,
  96.   720,268,734,520,520,188,634, 40,320,108,534,408,120, 28,434,776,
  97.   768,796,334,296,568,716,234,664,368,636,134,184,168,556, 34,552,
  98.   816,476,782, 72,616,396,682,440,416,316,582,808,216,236,482,328,
  99.    16,156,382,696,664, 76,282,216,464,844,182,584,264,764, 82,104,
  100.    64,684,830,472,712,604,730,840,512,524,630,360,312,444,530,728,
  101.   112,364,430,248,760,284,330,616,560,204,230,136,360,124,130,504,
  102.   160, 44, 30, 24,808,812,778,392,608,732,678,760,408,652,578,280,
  103.   208,572,478,648,  8,492,378,168,656,412,278,536,456,332,178, 56,
  104.   256,252, 78,424, 56,172,826,792,704, 92,726,312,504, 12,626,680,
  105.   304,780,526,200,104,700,426,568,752,620,326, 88,552,540,226,456,
  106.   352,460,126,824,152,380, 26,344,800,300,774,712,600,220,674,232,
  107.   400,140,574,600,200, 60,474,120,  0,828,374,488,648,748,274,  8,
  108.   448,668,174,376,248,588, 74,744, 48,508,822,264,696,428,722,632,
  109.   496,348,622,152,296,268,522,520, 96,188,422, 40,744,108,322,408,
  110.   544, 28,222,776,344,796,122,296,144,716, 22,664,792,636,770,184,
  111.   592,556,670,552,392,476,570, 72,192,396,470,440,840,316,370,808,
  112.   640,236,270,328,440,156,170,696,240, 76, 70,216, 40,844,818,584,
  113.   688,764,718,104,488,684,618,472,288,604,518,840, 88,524,418,360,
  114.   736,444,318,728,536,364,218,248,336,284,118,616,136,204, 18,136,
  115.   784,124,766,504,584, 44,666, 24,384,812,566,392,184,732,466,760,
  116.   832,652,366,280,632,572,266,648,432,492,166,168,232,412, 66,536,
  117.    32,332,814, 56,680,252,714,424,480,172,614,792,280, 92,514,312,
  118.    80, 12,414,680,728,780,314,200,528,700,214,568,328,620,114, 88,
  119.   128,540, 14,456,776,460,762,824,576,380,662,344,376,300,562,712,
  120.   176,220,462,232,824,140,362,600,624, 60,262,120,424,828,162,488,
  121.   224,748, 62,  8, 24,668,810,376,672,588,710,744,472,508,610,264,
  122.   272,428,510,632, 72,348,410,152,720,268,310,520,520,188,210, 40,
  123.   320,108,110,408,120, 28, 10,776,768,796,758,296,568,716,658,664,
  124.   368,636,558,184,168,556,458,552,816,476,358, 72,616,396,258,440,
  125.   416,316,158,808,216,236, 58,328, 16,156,806,696,664, 76,706,216,
  126.   464,844,606,584,264,764,506,104, 64,684,406,472,712,604,306,840,
  127.   512,524,206,360,312,444,106,728,112,364,  6,248,760,284,754,616,
  128.   560,204,654,136,360,124,554,504,160, 44,454, 24,808,812,354,392,
  129.   608,732,254,760,408,652,154,280,208,572, 54,648,  8,492,802,168,
  130.   656,412,702,536,456,332,602, 56,256,252,502,424, 56,172,402,792,
  131.   704, 92,302,312,504, 12,202,680,304,780,102,200,104,700,  2,568,
  132.   752,620,750, 88,552,540,650,456,352,460,550,824,152,380,450,344,
  133.   800,300,350,712,600,220,250,232,400,140,150,600,200, 60, 50,120,
  134.     0,828,798,488,648,748,698,  8,448,668,598,376,248,588,498,744,
  135.    48,508,398,264,696,428,298,632,496,348,198,152,296,268, 98,520,
  136.    96,188,846, 40,744,108,746,408,544, 28,646,776,344,796,546,296,
  137.   144,716,446,664,792,636,346,184,592,556,246,552,392,476,146, 72,
  138.   192,396, 46,440,840,316,794,808,640,236,694,328,440,156,594,696,
  139.   240, 76,494,216, 40,844,394,584,688,764,294,104,488,684,194,472,
  140.   288,604, 94,840, 88,524,842,360,736,444,742,728,536,364,642,248,
  141.   336,284,542,616,136,204,442,136,784,124,342,504,584, 44,242, 24,
  142. };
  143.  
  144. #define CCDWID 848
  145. #define CCDHEI 976
  146. #define CCDOFF 15680
  147.  
  148. /* Storage for the CCD data */
  149. unsigned char ccd[CCDHEI][CCDWID];
  150.  
  151. /* Storage for red, green, blue data, before expanding 1.5x */
  152. unsigned char red[CCDHEI][CCDWID];
  153. unsigned char gre[CCDHEI][CCDWID];
  154. unsigned char blu[CCDHEI][CCDWID];
  155.  
  156. unsigned char hdr[CCDOFF];
  157.  
  158. void main(int argc, char **argv)
  159. {
  160.   FILE *kdc;
  161.   FILE *bmp;
  162.  
  163.   char name[512];
  164.  
  165.   int  j, k;
  166.  
  167.   fprintf(stdout, "\n"
  168.                   "KDC2BMP - convert Kodak's DC120 .KDC file format to .BMP\n"
  169.                   "Based on code by Ed Hamrick, http://www.hamrick.com\n"
  170.                   "OS/2 version compiled by Stéphane Charette, charette@writeme.com\n\n" );
  171.  
  172.   /* Make sure called with only one argument */
  173.   if (argc != 2)
  174.   {
  175.     fprintf(stderr, "Usage: kdc2bmp.exe filename\n\n"
  176.                      "Note that you must not specify the file extension,\n"
  177.                      "and that only uncompressed .KDC files are supported.\n");
  178.     return;
  179.   }
  180.  
  181.   /* Open the .kdc file */
  182.   strcpy(name, argv[1]);
  183.   strcat(name, ".kdc");
  184.   kdc = fopen(name, "rb");
  185.   fprintf(stdout, "...reading %s...\n", name );
  186.   if (!kdc)
  187.   {
  188.     fprintf(stderr,"Error: can't open %s\n",name);
  189.     return;
  190.   }
  191.  
  192.   /* Verify that it's an uncompressed .kdc file */
  193.   fread(hdr, 1, sizeof(hdr), kdc);
  194.  
  195.   if (strcmp(hdr+470, "Kodak DC120 ZOOM Digital Camera"))
  196.   {
  197.     fprintf(stderr, "Error: not a DC120 .kdc file\n");
  198.     return;
  199.   }
  200.  
  201.   if (hdr[707] != 1)
  202.   {
  203.     fprintf(stderr, "Error: not an uncompressed .kdc file\n");
  204.     return;
  205.   }
  206.  
  207.   /* Read in and rotate the uncompressed data */
  208.   for (k=0; k<CCDHEI; k++)
  209.   {
  210.     for (j=0; j<CCDWID; j++)
  211.     {
  212.       ccd[k][(j-kdcoff[k]+CCDWID) % CCDWID] = fgetc(kdc);
  213.     }
  214.   }
  215.  
  216.   /* Close the .kdc file */
  217.   fclose(kdc);
  218.  
  219.   /* Use pixel replication to start */
  220.   for (k=0; k<CCDHEI; k+=2)
  221.   {
  222.     for (j=0; j<CCDWID; j+=2)
  223.     {
  224.       red[k  ][j  ] = ccd[k  ][j+1];
  225.       red[k  ][j+1] = ccd[k  ][j+1];
  226.       red[k+1][j  ] = ccd[k  ][j+1];
  227.       red[k+1][j+1] = ccd[k  ][j+1];
  228.  
  229.       gre[k  ][j  ] = ccd[k  ][j  ];
  230.       gre[k  ][j+1] = ccd[k  ][j  ];
  231.       gre[k+1][j  ] = ccd[k+1][j+1];
  232.       gre[k+1][j+1] = ccd[k+1][j+1];
  233.  
  234.       blu[k  ][j  ] = ccd[k+1][j  ];
  235.       blu[k  ][j+1] = ccd[k+1][j  ];
  236.       blu[k+1][j  ] = ccd[k+1][j  ];
  237.       blu[k+1][j+1] = ccd[k+1][j  ];
  238.     }
  239.   }
  240.  
  241.   /* Compute the interpolated red data */
  242.   for (k=2; k<CCDHEI-2; k+=2)
  243.   {
  244.     for (j=3; j<CCDWID-2; j+=2)
  245.     {
  246.       /* Get the left, bottom, corner red pixels */
  247.       unsigned char r, rl, rb, rc;
  248.  
  249.       r  = ccd[k  ][j  ];
  250.       rl = ccd[k  ][j-2];
  251.       rb = ccd[k+2][j  ];
  252.       rc = ccd[k+2][j-2];
  253.  
  254.       red[k  ][j-1] = (r + rl          ) / 2;
  255.       red[k+1][j  ] = (r      + rb     ) / 2;
  256.       red[k+1][j-1] = (r + rl + rb + rc) / 4;
  257.     }
  258.   }
  259.  
  260.   /* Compute the interpolated green data */
  261.   for (k=2; k<CCDHEI-2; k+=2)
  262.   {
  263.     for (j=3; j<CCDWID-2; j+=2)
  264.     {
  265.       /* Get the left, right, top, bottom green pixels */
  266.       unsigned char gl, gr, gt, gb;
  267.  
  268.       gl = ccd[k  ][j-1];
  269.       gr = ccd[k  ][j+1];
  270.       gt = ccd[k-1][j  ];
  271.       gb = ccd[k+1][j  ];
  272.  
  273.       gre[k][j] = (gl + gr + gt + gb) / 4;
  274.     }
  275.   }
  276.  
  277.   for (k=3; k<CCDHEI-2; k+=2)
  278.   {
  279.     for (j=2; j<CCDWID-2; j+=2)
  280.     {
  281.       /* Get the left, right, top, bottom green pixels */
  282.       unsigned char gl, gr, gt, gb;
  283.  
  284.       gl = ccd[k  ][j-1];
  285.       gr = ccd[k  ][j+1];
  286.       gt = ccd[k-1][j  ];
  287.       gb = ccd[k+1][j  ];
  288.  
  289.       gre[k][j] = (gl + gr + gt + gb) / 4;
  290.     }
  291.   }
  292.  
  293.   /* Compute the interpolated blue data */
  294.   for (k=3; k<CCDHEI-2; k+=2)
  295.   {
  296.     for (j=2; j<CCDWID-2; j+=2)
  297.     {
  298.       /* Get the right, top, corner blue pixels */
  299.       unsigned char b, br, bt, bc;
  300.  
  301.       b  = ccd[k  ][j  ];
  302.       br = ccd[k  ][j+2];
  303.       bt = ccd[k-2][j  ];
  304.       bc = ccd[k-2][j+2];
  305.  
  306.       blu[k  ][j+1] = (b + br          ) / 2;
  307.       blu[k-1][j  ] = (b      + bt     ) / 2;
  308.       blu[k-1][j+1] = (b + br + bt + bc) / 4;
  309.     }
  310.   }
  311.  
  312.   /* Open the .bmp file */
  313.   strcpy(name, argv[1]);
  314.   strcat(name, ".bmp");
  315.   fprintf(stdout, "...writing %s...\n", name );
  316.   bmp = fopen(name, "wb");
  317.   if (!bmp)
  318.   {
  319.     fprintf(stderr,"Error: can't create %s\n",name);
  320.     return;
  321.   }
  322.  
  323.   /* Write out the .bmp header */
  324.   fwrite(bmphead, 1, sizeof(bmphead), bmp);
  325.  
  326.   /* Write out the gamma corrected, stretched pixel data */
  327.   for (k=CCDHEI-1; k>=0; k--)
  328.   {
  329.     for (j=0; j<CCDWID; j+=2)
  330.     {
  331.       fputc(gamma[(blu[k][j]            )  ], bmp);
  332.       fputc(gamma[(gre[k][j]            )  ], bmp);
  333.       fputc(gamma[(red[k][j]            )  ], bmp);
  334.  
  335.       fputc(gamma[(blu[k][j]+blu[k][j+1])/2], bmp);
  336.       fputc(gamma[(gre[k][j]+gre[k][j+1])/2], bmp);
  337.       fputc(gamma[(red[k][j]+red[k][j+1])/2], bmp);
  338.  
  339.       fputc(gamma[(          blu[k][j+1])  ], bmp);
  340.       fputc(gamma[(          gre[k][j+1])  ], bmp);
  341.       fputc(gamma[(          red[k][j+1])  ], bmp);
  342.     }
  343.   }
  344.  
  345.   /* Close the .bmp file */
  346.   fclose(bmp);
  347. }
  348.  
  349.