home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / videotlk.zip / SAMPLES / EX4 / EX4CAP.C < prev    next >
Text File  |  1995-08-31  |  18KB  |  486 lines

  1.  
  2. /*------------------------------------------------------------------*
  3.  *                                                                  *
  4.  *  Video Toolkit For OS/2 Version 1.0                              *
  5.  *  Example PM Application No. 4.                                   *
  6.  *  Written by Stephen Sloan.                                       *
  7.  *  Date : 13/07/95.                                                *
  8.  *  Copyright Abbotsbury Software Ltd. (c), United Kingdom. 1995.   *
  9.  *                                                                  *
  10.  *  Filename : ex4cap.c                                             *
  11.  *                                                                  *
  12.  *------------------------------------------------------------------*/
  13.  
  14. #define     INCL_PM
  15. #define     INCL_DOS
  16. #define     INCL_SW
  17. #define     INCL_OS2MM
  18.  
  19. #include    <os2.h>
  20. #include    <os2me.h>
  21. #include    <stdio.h>
  22. #include    <stdlib.h>
  23. #include    <string.h>
  24. #include    <time.h>
  25. #include    <memory.h>
  26. #include    <malloc.h>
  27. #include    <vcadd.h>
  28. #include    <vcai.h>
  29. #include    "ex4.h"
  30. #include    "ex4cap.h"
  31. #include    "rgbconv.h"
  32.  
  33. extern  HAB     Hab;
  34. extern  HWND    HwndFrame, HwndClient;
  35. extern  LONG    Width, Height, X, Y;
  36. extern  BOOL    CaptureOpen, ConvertASM;
  37. extern  LONG    NumColours;
  38. extern  LONG    Colours[256];
  39.  
  40. extern  void    msg_box (UCHAR *txt, UCHAR *title, ULONG options);
  41. extern  void    err_msg (CHAR *text);
  42.  
  43. static  UCHAR   *Bmp_data;
  44. static  BITMAPINFOHEADER2   Bmp_ihdr;
  45. static  CHAR    txt[80];
  46.  
  47.  
  48.                         // function protocols.
  49. MRESULT EXPENTRY CaptureDlgProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  50.  
  51.                         // static function protocols.
  52. static  BOOL    create_bitmap_Hdc_Hps (PHDC phdc, PHPS phps);
  53. static  void    bmp_file_proc (void);
  54. static  LONG    hextol (char *t);
  55. static  void    convert_YUV422_RGB (BYTE *src, BYTE *dest, ULONG num);
  56. static  BYTE    get_colour (HPS hps, USHORT r, USHORT g, USHORT b);
  57.  
  58.                         // functions.
  59. MRESULT EXPENTRY CaptureDlgProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  60. {
  61.     static  HWND    hwnd_menu;
  62.     static  HBITMAP hbm;
  63.     static  HPS     hpsBMP;
  64.     static  HDC     hdcBMP;
  65.     static  LONG    x, y, width, height;
  66.     static  UCHAR   *buf, *data;
  67.     BITMAPINFO2     bmpi;
  68.     PBITMAPINFO2    pbmpi = &bmpi;
  69.     PBITMAPINFOHEADER2  pbmpih = &Bmp_ihdr;
  70.     ULONG   len, i, j, size;
  71.     ERRORID err;
  72.     LONG    bx, by, ty;
  73.     HPS     hps;
  74.     RECTL   rcl;
  75.     POINTL  pts;
  76.     APIRET  rc;
  77.     SWP     swp;
  78.  
  79.         switch (msg)
  80.         {
  81.             case WM_INITDLG :
  82.                 hwnd_menu = WinLoadMenu (hwnd, NULLHANDLE, IDD_CAPTURE);
  83.                 x = y = 0;
  84.                 bx = WinQuerySysValue (HWND_DESKTOP, SV_CXDLGFRAME);
  85.                 by = WinQuerySysValue (HWND_DESKTOP, SV_CYDLGFRAME);
  86.                 ty = WinQuerySysValue (HWND_DESKTOP, SV_CYTITLEBAR);
  87.                 WinSetWindowPos (hwnd, HWND_TOP, x, y,
  88.                                  Width + (bx * 2), Height + (by * 2) + ty,
  89.                                  SWP_SIZE | SWP_MOVE);
  90.                 WinSendMsg (hwnd, MSG_CAPTURE, NULL, NULL);
  91.                 CaptureOpen = TRUE;
  92.                 break;
  93.             case WM_PAINT :
  94.                 hps = WinBeginPaint (hwnd, NULLHANDLE, &rcl);
  95.                 WinQueryWindowRect (hwnd, &rcl);
  96.                 WinFillRect (hps, &rcl, CLR_PALEGRAY);
  97.                 bx = WinQuerySysValue (HWND_DESKTOP, SV_CXDLGFRAME);
  98.                 by = WinQuerySysValue (HWND_DESKTOP, SV_CYDLGFRAME);
  99.                 pts.x = 0 + bx;
  100.                 pts.y = 0 + by;
  101.                 WinDrawBitmap (hps, hbm, NULL, &pts, CLR_NEUTRAL,
  102.                                CLR_BACKGROUND, DBM_NORMAL | DBM_IMAGEATTRS);
  103.                 WinDrawBorder (hps, &rcl, bx, by, CLR_YELLOW,
  104.                                CLR_DARKGRAY, DB_AREAATTRS | DB_DLGBORDER);
  105.                 WinEndPaint (hps);
  106.                 break;
  107.             case WM_COMMAND :
  108.                 switch (SHORT1FROMMP (mp1))
  109.                 {
  110.                     case IDM_CAPT_FILE_SAVE :
  111.                         bmp_file_proc ();
  112.                         return 0;
  113.                     default :
  114.                         break;
  115.                 }
  116.                 return 0;
  117.             case WM_CLOSE :
  118.             case WM_QUIT :
  119.             case WM_DESTROY :
  120.                 GpiDestroyPS (hpsBMP);
  121.                 DevCloseDC (hdcBMP);
  122.                 GpiDeleteBitmap (hbm);
  123.                 DosFreeMem (Bmp_data);
  124.                 DosFreeMem (buf);
  125.                 CaptureOpen = FALSE;
  126.                 break;
  127.             case MSG_CAPTURE :
  128.                 if (hbm)
  129.                 {
  130.                     GpiDestroyPS (hpsBMP);
  131.                     DevCloseDC (hdcBMP);
  132.                     GpiDeleteBitmap (hbm);
  133.                 }
  134.  
  135.                 width = (Width / 8) * 8;
  136.                 height = (Height / 8) * 8;
  137.                 WinQueryWindowPos (hwnd, &swp);
  138.                 x = swp.x;
  139.                 y = swp.y;
  140.                 bx = WinQuerySysValue (HWND_DESKTOP, SV_CXDLGFRAME);
  141.                 by = WinQuerySysValue (HWND_DESKTOP, SV_CYDLGFRAME);
  142.                 ty = WinQuerySysValue (HWND_DESKTOP, SV_CYTITLEBAR);
  143.                 WinSetWindowPos (hwnd, HWND_TOP, x, swp.y,
  144.                                  Width + (bx * 2), Height + (by * 2) + (ty * 2),
  145.                                  SWP_SIZE | SWP_MOVE);
  146.                 len = (ULONG)((width * height) * 2);
  147.                 rc = DosAllocMem ((PPVOID)&buf, len + 4L,
  148.                                   (PAG_COMMIT | PAG_WRITE));
  149.                 if (rc)
  150.                 {
  151.                     sprintf (txt, "error - DosAllocMem %d", rc);
  152.                     msg_box (txt, "Error", MB_ERROR | MB_OK);
  153.                     return;
  154.                 }
  155.  
  156.                 rc = DosAllocMem ((PPVOID)&Bmp_data, (width * height * 4) + 4L,
  157.                                   (PAG_WRITE | PAG_COMMIT));
  158.                 if (rc)
  159.                 {
  160.                     sprintf (txt, "error - DosAllocMem %d", rc);
  161.                     msg_box (txt, "Error", MB_ERROR | MB_OK);
  162.                     return;
  163.                 }
  164.  
  165.                 if (!ConvertASM)
  166.                 {
  167.                     rc = DosAllocMem ((PPVOID)&data,
  168.                                       (width * height * 4) + 4L,
  169.                                       (PAG_WRITE | PAG_COMMIT));
  170.                     if (rc)
  171.                     {
  172.                         sprintf (txt, "error - DosAllocMem %d", rc);
  173.                         msg_box (txt, "Error", MB_ERROR | MB_OK);
  174.                         return;
  175.                     }
  176.                 }
  177.  
  178.                 VcaiImageScaleGet ((USHORT)len,   (ULONG)buf,
  179.                                    (USHORT)x,     (USHORT)(y + height),
  180.                                    (USHORT)width, (USHORT)height,
  181.                                    (USHORT)X,     (USHORT)Y,
  182.                                    (USHORT)width, (USHORT)height);
  183.  
  184.                 if (ConvertASM)
  185.                 {
  186.                     YUV422_TO_IRGB24 ((USHORT *)buf, (BYTE *)Bmp_data,
  187.                                       (ULONG)width,  (ULONG)height);
  188.                 }
  189.                 else
  190.                 {
  191.                     convert_YUV422_RGB (buf, data, len);
  192.  
  193.                                 // Transfer scan lines to bottom up.
  194.                     for (i = 0, j = (width * height) - width;
  195.                          i < height;
  196.                          i++, j-=width)
  197.                     {
  198.                         memcpy (Bmp_data + j, data + (i*width), (size_t)width);
  199.                     }
  200.                 }
  201.  
  202.                 if (ConvertASM)
  203.                 {
  204.                     pbmpi = malloc (sizeof (BITMAPINFO2));
  205.                 }
  206.                 else
  207.                 {
  208.                     size = (sizeof (RGB2)) * (NumColours - 1);
  209.                     pbmpi = malloc (sizeof (BITMAPINFO2) + size);
  210.                 }
  211.                 pbmpih->cbFix = pbmpi->cbFix = sizeof (BITMAPINFOHEADER2);
  212.                 pbmpih->cx            = pbmpi->cx            = width;
  213.                 pbmpih->cy            = pbmpi->cy            = height;
  214.                 pbmpih->cPlanes       = pbmpi->cPlanes       = 1;
  215.                 if (!ConvertASM)
  216.                 {
  217.                     switch ((ULONG)NumColours)
  218.                     {
  219.                         case 2 :
  220.                             pbmpih->cBitCount = pbmpi->cBitCount = 1;
  221.                             break;
  222.                         case 16 :
  223.                             pbmpih->cBitCount = pbmpi->cBitCount = 4;
  224.                             break;
  225.                         case 256 :
  226.                             pbmpih->cBitCount = pbmpi->cBitCount = 8;
  227.                             break;
  228.                         default:
  229.                             break;
  230.                     }
  231.                 }
  232.                 else
  233.                 {
  234.                     pbmpih->cBitCount     = pbmpi->cBitCount     = 24;
  235.                 }
  236.                 pbmpih->ulCompression = pbmpi->ulCompression = BCA_UNCOMP;
  237.                 pbmpih->cbImage       = pbmpi->cbImage       = 0L;
  238.                 pbmpih->cxResolution  = pbmpi->cxResolution  = width;
  239.                 pbmpih->cyResolution  = pbmpi->cyResolution  = height;
  240.                 if (!ConvertASM)
  241.                 {
  242.                     pbmpih->cclrUsed      = pbmpi->cclrUsed      = NumColours;
  243.                     pbmpih->cclrImportant = pbmpi->cclrImportant = NumColours;
  244.                 }
  245.                 else
  246.                 {
  247.                     pbmpih->cclrUsed      = pbmpi->cclrUsed      = 0L;
  248.                     pbmpih->cclrImportant = pbmpi->cclrImportant = 0L;
  249.                 }
  250.                 pbmpih->usUnits       = pbmpi->usUnits       = BRU_METRIC;
  251.                 pbmpih->usReserved    = pbmpi->usReserved    = 0;
  252.                 pbmpih->usRecording   = pbmpi->usRecording   = BRA_BOTTOMUP;
  253.                 pbmpih->usRendering   = pbmpi->usRendering   = BRH_NOTHALFTONED;
  254.                 pbmpih->cSize1        = pbmpi->cSize1        = 0L;
  255.                 pbmpih->cSize2        = pbmpi->cSize2        = 0L;
  256.                 pbmpih->ulColorEncoding = pbmpi->ulColorEncoding = BCE_RGB;
  257.                 if (!ConvertASM)
  258.                 {
  259.                     for (i = 0; i < NumColours; i++)
  260.                     {
  261.                         pbmpi->argbColor[i].bBlue  =
  262.                                            (BYTE)(Colours[i] & 0x000000FF);
  263.                         pbmpi->argbColor[i].bGreen =
  264.                                     (BYTE)((Colours[i] & 0x0000FF00) / 0x100);
  265.                         pbmpi->argbColor[i].bRed   =
  266.                                   (BYTE)((Colours[i] & 0x00FF0000) / 0x10000);
  267.                         pbmpi->argbColor[i].fcOptions = 0;
  268.                     }
  269.                 }
  270.                 create_bitmap_Hdc_Hps (&hdcBMP, &hpsBMP);
  271.                 hbm = GpiCreateBitmap (hpsBMP, pbmpih, 0L, NULL, NULL);
  272.                 if (hbm == 0)
  273.                 {
  274.                     err_msg ("GpiCreateBitmap");
  275.                     return;
  276.                 }
  277.                 if (GpiSetBitmap (hpsBMP, hbm) == HBM_ERROR)
  278.                 {
  279.                     err_msg ("GpiSetBitmap");
  280.                     return;
  281.                 }
  282.                 if (GpiSetBitmapBits (hpsBMP, 0L, height, Bmp_data, pbmpi)
  283.                     != height)
  284.                 {
  285.                     err_msg ("GpiSetBitmapBits");
  286.                     return;
  287.                 }
  288.                 DosFreeMem (data);
  289.                 DosFreeMem (buf);
  290.                 DosFreeMem (Bmp_data);
  291.                 free (pbmpi);
  292.                 WinQueryWindowRect (hwnd, &rcl);
  293.                 WinInvalidateRect (hwnd, &rcl, TRUE);
  294.                 break;
  295.             default :
  296.                 break;
  297.         }
  298.         return WinDefDlgProc (hwnd, msg, mp1, mp2);
  299. }
  300.  
  301. static BOOL create_bitmap_Hdc_Hps (PHDC phdc, PHPS phps)
  302. {
  303.     SIZEL    sizl;
  304.     HDC      hdc;
  305.     HPS      hps;
  306.     DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL,
  307.                         NULL};
  308.  
  309.         hdc = DevOpenDC (Hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA) &dop,
  310.                          NULLHANDLE);
  311.         if (!hdc)
  312.             return (FALSE);
  313.  
  314.         sizl.cx = sizl.cy = 1L;
  315.         hps = GpiCreatePS (Hab, hdc, &sizl, PU_PELS | GPIA_ASSOC | GPIT_MICRO);
  316.         if (!hps)
  317.             return (FALSE);
  318.  
  319.         *phdc = hdc;
  320.         *phps = hps;
  321.         return (TRUE);
  322. }
  323.  
  324. static void bmp_file_proc ()
  325. {
  326.     HWND    hwndDlg;
  327.     CHAR    title[20];
  328.     FILE    *fd;
  329.     BYTE    *d;
  330.     LONG    width, height;
  331.     ULONG   i;
  332.     FILEDLG file_dlg;
  333.     BITMAPFILEHEADER2   bmp_fhdr;
  334.  
  335.                                     // initialise FILEDLG structure.
  336.         memset (&file_dlg, 0, sizeof (FILEDLG));
  337.         file_dlg.cbSize = sizeof (FILEDLG);
  338.         file_dlg.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_SAVEAS_DIALOG;
  339.         sprintf (title, "Save bitmap");
  340.         file_dlg.pszTitle = title;
  341.         sprintf (file_dlg.szFullFile, "*.bmp");
  342.  
  343.                                     // open file dialog.
  344.         hwndDlg = WinFileDlg (HWND_DESKTOP, HwndFrame, &file_dlg);
  345.         if (hwndDlg && (file_dlg.lReturn != DID_OK))
  346.             return;
  347.  
  348.                                     // save bitmap.
  349.         fd = fopen (file_dlg.szFullFile, "wb");
  350.         if (!fd)
  351.             return;
  352.         bmp_fhdr.usType  = BFT_BMAP;
  353.         bmp_fhdr.cbSize  = sizeof (BITMAPFILEHEADER2);
  354.         bmp_fhdr.offBits = bmp_fhdr.cbSize;
  355.         bmp_fhdr.bmp2    = Bmp_ihdr;
  356.         d = (BYTE *)&bmp_fhdr;
  357.         for (i = 0; i < (sizeof (BITMAPFILEHEADER2)); i++, d++)
  358.             fputc ((INT) *d, fd);
  359.         width = (Width / 8) * 8;
  360.         height = (Height / 8) * 8;
  361.         for (i = 0; i < (width * height * 4); i++)
  362.             fputc (Bmp_data[i], fd);
  363.         fclose (fd);
  364. }
  365.  
  366. static LONG hextol (char *t)
  367. {
  368.     LONG tot;
  369.  
  370.         tot = 0L;
  371.  
  372.         while (*t)
  373.         {
  374.             if (*t >= '0' && *t <= '9')
  375.                 break;
  376.             if (*t >= 'a' && *t <= 'f')
  377.                 break;
  378.             if (*t >= 'A' && *t <= 'F')
  379.                 break;
  380.             t++;
  381.         }
  382.         while (*t)
  383.         {
  384.             if ((!(*t >= '0' && *t <= '9')) &&
  385.                 (!(*t >= 'a' && *t <= 'f')) &&
  386.                 (!(*t >= 'A' && *t <= 'F')))
  387.                 break;
  388.  
  389.             if (*t >= '0' && *t <= '9')
  390.             {
  391.                 tot *= 16L;
  392.                 tot += (*t - '0');
  393.                 t++;
  394.                 continue;
  395.             }
  396.             if (*t >= 'a' && *t <= 'f')
  397.             {
  398.                 tot *= 16L;
  399.                 tot += (*t - 'a') + 0xA;
  400.                 t++;
  401.                 continue;
  402.             }
  403.             if (*t >= '0' && *t <= '9')
  404.             {
  405.                 tot *= 16L;
  406.                 tot += (*t - 'A') + 0xA;
  407.                 t++;
  408.                 continue;
  409.             }
  410.         }
  411.         return tot;
  412. }
  413.  
  414. static void convert_YUV422_RGB (BYTE *src, BYTE *dest, ULONG len)
  415. {
  416.     /*
  417.         Convert YUV 4:2:2 image data to RGB format for use in creating
  418.         a bitmap of the image. This code only supports resolutions with
  419.         256 colours.
  420.  
  421.         Rt = (V * 179) / 127.
  422.         Bt = (U * 227) / 127.
  423.         R1 = Rt + Y1.
  424.         R2 = Rt + Y2.
  425.         B1 = Bt + Y1.
  426.         B2 = Bt + Y2.
  427.         G1 = ((170 * Y1) - (51 * R1) - (19 * B1)) / 100.
  428.         G2 = ((170 * Y2) - (51 * R2) - (19 * B2)) / 100.
  429.     */
  430.  
  431.     USHORT  R1, R2, G1, G2, B1, B2, Y1, Y2, Rt, Bt;
  432.     SHORT   U, V;
  433.     LONG    RGB1, RGB2, d;
  434.     ULONG   i, j;
  435.     HPS     hps;
  436.  
  437.         hps = WinGetPS (HwndClient);
  438.         if (!GpiCreateLogColorTable (hps, LCOL_RESET, LCOLF_CONSECRGB, 0L,
  439.                                      NumColours, Colours))
  440.             err_msg ("GpiCreateLogColorTable");
  441.         for (i = 0, j = 0; i < len; i+=4, j+=2)
  442.         {
  443.             Y1 = (USHORT)(src[i] & 0xff);
  444.             U  = (SHORT)(src[i+1] & 0xff);
  445.             Y2 = (USHORT)(src[i+2] & 0xff);
  446.             V  = (SHORT)(src[i+3] & 0xff);
  447.             U -= 128;
  448.             V -= 128;
  449.             Rt = (V * 179) / 127;
  450.             Bt = (U * 227) / 127;
  451.             R1 = Rt + Y1;
  452.             R2 = Rt + Y2;
  453.             B1 = Bt + Y1;
  454.             B2 = Bt + Y2;
  455.             G1 = ((170 * Y1) - (51 * R1) - (19 * B1)) / 100;
  456.             G2 = ((170 * Y2) - (51 * R2) - (19 * B2)) / 100;
  457.             R1 = (R1 >= 0x100) ? 0xFF :
  458.                  (R1 <= 0) ? 0 : R1;
  459.             R2 = (R2 >= 0x100) ? 0xFF :
  460.                  (R2 <= 0) ? 0 : R2;
  461.             B1 = (B1 >= 0x100) ? 0xFF :
  462.                  (B1 <= 0) ? 0 : B1;
  463.             B2 = (B2 >= 0x100) ? 0xFF :
  464.                  (B2 <= 0) ? 0 : B2;
  465.             G1 = (G1 >= 0x100) ? 0xFF :
  466.                  (G1 <= 0) ? 0 : G1;
  467.             G2 = (G2 >= 0x100) ? 0xFF :
  468.                  (G2 <= 0) ? 0 : G2;
  469.             dest[j]   = get_colour (hps, R1, G1, B1);
  470.             dest[j+1] = get_colour (hps, R2, G2, B2);
  471.         }
  472.         WinReleasePS (hps);
  473. }
  474.  
  475. static BYTE get_colour (HPS hps, USHORT r, USHORT g, USHORT b)
  476. {
  477.     ULONG   i;
  478.     LONG    d;
  479.     LONG    rgb;
  480.  
  481.         rgb = (LONG)((r * 0x10000) + (g * 0x100) + b);
  482.         rgb = GpiQueryNearestColor (hps, 0, rgb);
  483.         d = GpiQueryColorIndex (hps, 0, rgb);
  484.         return (BYTE)(d & 0xff);
  485. }
  486.