home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
videotlk.zip
/
SAMPLES
/
EX5
/
EX5CAP.C
< prev
next >
Wrap
Text File
|
1999-02-25
|
18KB
|
485 lines
/*------------------------------------------------------------------*
* *
* Video Toolkit For OS/2 Version 1.0 *
* Example PM Application No. 5. *
* Date : 13/07/95. *
* Copyright Abbotsbury Software Ltd. (c), United Kingdom. 1999. *
* *
* Filename : ex5cap.c *
* *
*------------------------------------------------------------------*/
#define INCL_PM
#define INCL_DOS
#define INCL_SW
#define INCL_OS2MM
#include <os2.h>
#include <os2me.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <memory.h>
#include <malloc.h>
#include <vcadd.h>
#include <vcai.h>
#include "ex5.h"
#include "ex5cap.h"
#include "rgbconv.h"
extern HAB Hab;
extern HWND HwndFrame, HwndClient;
extern LONG Width, Height, X, Y;
extern BOOL CaptureOpen, ConvertASM;
extern LONG NumColours;
extern LONG Colours[256];
extern void msg_box (UCHAR *txt, UCHAR *title, ULONG options);
extern void err_msg (CHAR *text);
static UCHAR *Bmp_data;
static BITMAPINFOHEADER2 Bmp_ihdr;
static CHAR txt[80];
// function protocols.
MRESULT EXPENTRY CaptureDlgProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
// static function protocols.
static BOOL create_bitmap_Hdc_Hps (PHDC phdc, PHPS phps);
static void bmp_file_proc (void);
static LONG hextol (char *t);
static void convert_YUV422_RGB (BYTE *src, BYTE *dest, ULONG num);
static BYTE get_colour (HPS hps, USHORT r, USHORT g, USHORT b);
// functions.
MRESULT EXPENTRY CaptureDlgProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
static HWND hwnd_menu;
static HBITMAP hbm;
static HPS hpsBMP;
static HDC hdcBMP;
static LONG x, y, width, height;
static UCHAR *buf, *data;
BITMAPINFO2 bmpi;
PBITMAPINFO2 pbmpi = &bmpi;
PBITMAPINFOHEADER2 pbmpih = &Bmp_ihdr;
ULONG len, i, j, size;
ERRORID err;
LONG bx, by, ty;
HPS hps;
RECTL rcl;
POINTL pts;
APIRET rc;
SWP swp;
switch (msg)
{
case WM_INITDLG :
hwnd_menu = WinLoadMenu (hwnd, NULLHANDLE, IDD_CAPTURE);
x = y = 0;
bx = WinQuerySysValue (HWND_DESKTOP, SV_CXDLGFRAME);
by = WinQuerySysValue (HWND_DESKTOP, SV_CYDLGFRAME);
ty = WinQuerySysValue (HWND_DESKTOP, SV_CYTITLEBAR);
WinSetWindowPos (hwnd, HWND_TOP, x, y,
Width + (bx * 2), Height + (by * 2) + ty,
SWP_SIZE | SWP_MOVE);
WinSendMsg (hwnd, MSG_CAPTURE, NULL, NULL);
CaptureOpen = TRUE;
break;
case WM_PAINT :
hps = WinBeginPaint (hwnd, NULLHANDLE, &rcl);
WinQueryWindowRect (hwnd, &rcl);
WinFillRect (hps, &rcl, CLR_PALEGRAY);
bx = WinQuerySysValue (HWND_DESKTOP, SV_CXDLGFRAME);
by = WinQuerySysValue (HWND_DESKTOP, SV_CYDLGFRAME);
pts.x = 0 + bx;
pts.y = 0 + by;
WinDrawBitmap (hps, hbm, NULL, &pts, CLR_NEUTRAL,
CLR_BACKGROUND, DBM_NORMAL | DBM_IMAGEATTRS);
WinDrawBorder (hps, &rcl, bx, by, CLR_YELLOW,
CLR_DARKGRAY, DB_AREAATTRS | DB_DLGBORDER);
WinEndPaint (hps);
break;
case WM_COMMAND :
switch (SHORT1FROMMP (mp1))
{
case IDM_CAPT_FILE_SAVE :
bmp_file_proc ();
return 0;
default :
break;
}
return 0;
case WM_CLOSE :
case WM_QUIT :
case WM_DESTROY :
GpiDestroyPS (hpsBMP);
DevCloseDC (hdcBMP);
GpiDeleteBitmap (hbm);
DosFreeMem (Bmp_data);
DosFreeMem (buf);
CaptureOpen = FALSE;
break;
case MSG_CAPTURE :
if (hbm)
{
GpiDestroyPS (hpsBMP);
DevCloseDC (hdcBMP);
GpiDeleteBitmap (hbm);
}
width = (Width / 8) * 8;
height = (Height / 8) * 8;
WinQueryWindowPos (hwnd, &swp);
x = swp.x;
y = swp.y;
bx = WinQuerySysValue (HWND_DESKTOP, SV_CXDLGFRAME);
by = WinQuerySysValue (HWND_DESKTOP, SV_CYDLGFRAME);
ty = WinQuerySysValue (HWND_DESKTOP, SV_CYTITLEBAR);
WinSetWindowPos (hwnd, HWND_TOP, x, swp.y,
Width + (bx * 2), Height + (by * 2) + (ty * 2),
SWP_SIZE | SWP_MOVE);
len = (ULONG)((width * height) * 2);
rc = DosAllocMem ((PPVOID)&buf, len + 4L,
(PAG_COMMIT | PAG_WRITE));
if (rc)
{
sprintf (txt, "error - DosAllocMem %d", rc);
msg_box (txt, "Error", MB_ERROR | MB_OK);
return;
}
rc = DosAllocMem ((PPVOID)&Bmp_data, (width * height * 4) + 4L,
(PAG_WRITE | PAG_COMMIT));
if (rc)
{
sprintf (txt, "error - DosAllocMem %d", rc);
msg_box (txt, "Error", MB_ERROR | MB_OK);
return;
}
if (!ConvertASM)
{
rc = DosAllocMem ((PPVOID)&data,
(width * height * 4) + 4L,
(PAG_WRITE | PAG_COMMIT));
if (rc)
{
sprintf (txt, "error - DosAllocMem %d", rc);
msg_box (txt, "Error", MB_ERROR | MB_OK);
return;
}
}
VcaiImageScaleGet ((USHORT)len, (ULONG)buf,
(USHORT)x, (USHORT)(y + height),
(USHORT)width, (USHORT)height,
(USHORT)X, (USHORT)Y,
(USHORT)width, (USHORT)height);
if (ConvertASM)
{
YUV422_TO_IRGB24 ((USHORT *)buf, (BYTE *)Bmp_data,
(ULONG)width, (ULONG)height);
}
else
{
convert_YUV422_RGB (buf, data, len);
// Transfer scan lines to bottom up.
for (i = 0, j = (width * height) - width;
i < height;
i++, j-=width)
{
memcpy (Bmp_data + j, data + (i*width), (size_t)width);
}
}
if (ConvertASM)
{
pbmpi = malloc (sizeof (BITMAPINFO2));
}
else
{
size = (sizeof (RGB2)) * (NumColours - 1);
pbmpi = malloc (sizeof (BITMAPINFO2) + size);
}
pbmpih->cbFix = pbmpi->cbFix = sizeof (BITMAPINFOHEADER2);
pbmpih->cx = pbmpi->cx = width;
pbmpih->cy = pbmpi->cy = height;
pbmpih->cPlanes = pbmpi->cPlanes = 1;
if (!ConvertASM)
{
switch ((ULONG)NumColours)
{
case 2 :
pbmpih->cBitCount = pbmpi->cBitCount = 1;
break;
case 16 :
pbmpih->cBitCount = pbmpi->cBitCount = 4;
break;
case 256 :
pbmpih->cBitCount = pbmpi->cBitCount = 8;
break;
default:
break;
}
}
else
{
pbmpih->cBitCount = pbmpi->cBitCount = 24;
}
pbmpih->ulCompression = pbmpi->ulCompression = BCA_UNCOMP;
pbmpih->cbImage = pbmpi->cbImage = 0L;
pbmpih->cxResolution = pbmpi->cxResolution = width;
pbmpih->cyResolution = pbmpi->cyResolution = height;
if (!ConvertASM)
{
pbmpih->cclrUsed = pbmpi->cclrUsed = NumColours;
pbmpih->cclrImportant = pbmpi->cclrImportant = NumColours;
}
else
{
pbmpih->cclrUsed = pbmpi->cclrUsed = 0L;
pbmpih->cclrImportant = pbmpi->cclrImportant = 0L;
}
pbmpih->usUnits = pbmpi->usUnits = BRU_METRIC;
pbmpih->usReserved = pbmpi->usReserved = 0;
pbmpih->usRecording = pbmpi->usRecording = BRA_BOTTOMUP;
pbmpih->usRendering = pbmpi->usRendering = BRH_NOTHALFTONED;
pbmpih->cSize1 = pbmpi->cSize1 = 0L;
pbmpih->cSize2 = pbmpi->cSize2 = 0L;
pbmpih->ulColorEncoding = pbmpi->ulColorEncoding = BCE_RGB;
if (!ConvertASM)
{
for (i = 0; i < NumColours; i++)
{
pbmpi->argbColor[i].bBlue =
(BYTE)(Colours[i] & 0x000000FF);
pbmpi->argbColor[i].bGreen =
(BYTE)((Colours[i] & 0x0000FF00) / 0x100);
pbmpi->argbColor[i].bRed =
(BYTE)((Colours[i] & 0x00FF0000) / 0x10000);
pbmpi->argbColor[i].fcOptions = 0;
}
}
create_bitmap_Hdc_Hps (&hdcBMP, &hpsBMP);
hbm = GpiCreateBitmap (hpsBMP, pbmpih, 0L, NULL, NULL);
if (hbm == 0)
{
err_msg ("GpiCreateBitmap");
return;
}
if (GpiSetBitmap (hpsBMP, hbm) == HBM_ERROR)
{
err_msg ("GpiSetBitmap");
return;
}
if (GpiSetBitmapBits (hpsBMP, 0L, height, Bmp_data, pbmpi)
!= height)
{
err_msg ("GpiSetBitmapBits");
return;
}
DosFreeMem (data);
DosFreeMem (buf);
DosFreeMem (Bmp_data);
free (pbmpi);
WinQueryWindowRect (hwnd, &rcl);
WinInvalidateRect (hwnd, &rcl, TRUE);
break;
default :
break;
}
return WinDefDlgProc (hwnd, msg, mp1, mp2);
}
static BOOL create_bitmap_Hdc_Hps (PHDC phdc, PHPS phps)
{
SIZEL sizl;
HDC hdc;
HPS hps;
DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL,
NULL};
hdc = DevOpenDC (Hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA) &dop,
NULLHANDLE);
if (!hdc)
return (FALSE);
sizl.cx = sizl.cy = 1L;
hps = GpiCreatePS (Hab, hdc, &sizl, PU_PELS | GPIA_ASSOC | GPIT_MICRO);
if (!hps)
return (FALSE);
*phdc = hdc;
*phps = hps;
return (TRUE);
}
static void bmp_file_proc ()
{
HWND hwndDlg;
CHAR title[20];
FILE *fd;
BYTE *d;
LONG width, height;
ULONG i;
FILEDLG file_dlg;
BITMAPFILEHEADER2 bmp_fhdr;
// initialise FILEDLG structure.
memset (&file_dlg, 0, sizeof (FILEDLG));
file_dlg.cbSize = sizeof (FILEDLG);
file_dlg.fl = FDS_HELPBUTTON | FDS_CENTER | FDS_SAVEAS_DIALOG;
sprintf (title, "Save bitmap");
file_dlg.pszTitle = title;
sprintf (file_dlg.szFullFile, "*.bmp");
// open file dialog.
hwndDlg = WinFileDlg (HWND_DESKTOP, HwndFrame, &file_dlg);
if (hwndDlg && (file_dlg.lReturn != DID_OK))
return;
// save bitmap.
fd = fopen (file_dlg.szFullFile, "wb");
if (!fd)
return;
bmp_fhdr.usType = BFT_BMAP;
bmp_fhdr.cbSize = sizeof (BITMAPFILEHEADER2);
bmp_fhdr.offBits = bmp_fhdr.cbSize;
bmp_fhdr.bmp2 = Bmp_ihdr;
d = (BYTE *)&bmp_fhdr;
for (i = 0; i < (sizeof (BITMAPFILEHEADER2)); i++, d++)
fputc ((INT) *d, fd);
width = (Width / 8) * 8;
height = (Height / 8) * 8;
for (i = 0; i < (width * height * 4); i++)
fputc (Bmp_data[i], fd);
fclose (fd);
}
static LONG hextol (char *t)
{
LONG tot;
tot = 0L;
while (*t)
{
if (*t >= '0' && *t <= '9')
break;
if (*t >= 'a' && *t <= 'f')
break;
if (*t >= 'A' && *t <= 'F')
break;
t++;
}
while (*t)
{
if ((!(*t >= '0' && *t <= '9')) &&
(!(*t >= 'a' && *t <= 'f')) &&
(!(*t >= 'A' && *t <= 'F')))
break;
if (*t >= '0' && *t <= '9')
{
tot *= 16L;
tot += (*t - '0');
t++;
continue;
}
if (*t >= 'a' && *t <= 'f')
{
tot *= 16L;
tot += (*t - 'a') + 0xA;
t++;
continue;
}
if (*t >= '0' && *t <= '9')
{
tot *= 16L;
tot += (*t - 'A') + 0xA;
t++;
continue;
}
}
return tot;
}
static void convert_YUV422_RGB (BYTE *src, BYTE *dest, ULONG len)
{
/*
Convert YUV 4:2:2 image data to RGB format for use in creating
a bitmap of the image. This code only supports resolutions with
256 colours.
Rt = (V * 179) / 127.
Bt = (U * 227) / 127.
R1 = Rt + Y1.
R2 = Rt + Y2.
B1 = Bt + Y1.
B2 = Bt + Y2.
G1 = ((170 * Y1) - (51 * R1) - (19 * B1)) / 100.
G2 = ((170 * Y2) - (51 * R2) - (19 * B2)) / 100.
*/
USHORT R1, R2, G1, G2, B1, B2, Y1, Y2, Rt, Bt;
SHORT U, V;
LONG RGB1, RGB2, d;
ULONG i, j;
HPS hps;
hps = WinGetPS (HwndClient);
if (!GpiCreateLogColorTable (hps, LCOL_RESET, LCOLF_CONSECRGB, 0L,
NumColours, Colours))
err_msg ("GpiCreateLogColorTable");
for (i = 0, j = 0; i < len; i+=4, j+=2)
{
Y1 = (USHORT)(src[i] & 0xff);
U = (SHORT)(src[i+1] & 0xff);
Y2 = (USHORT)(src[i+2] & 0xff);
V = (SHORT)(src[i+3] & 0xff);
U -= 128;
V -= 128;
Rt = (V * 179) / 127;
Bt = (U * 227) / 127;
R1 = Rt + Y1;
R2 = Rt + Y2;
B1 = Bt + Y1;
B2 = Bt + Y2;
G1 = ((170 * Y1) - (51 * R1) - (19 * B1)) / 100;
G2 = ((170 * Y2) - (51 * R2) - (19 * B2)) / 100;
R1 = (R1 >= 0x100) ? 0xFF :
(R1 <= 0) ? 0 : R1;
R2 = (R2 >= 0x100) ? 0xFF :
(R2 <= 0) ? 0 : R2;
B1 = (B1 >= 0x100) ? 0xFF :
(B1 <= 0) ? 0 : B1;
B2 = (B2 >= 0x100) ? 0xFF :
(B2 <= 0) ? 0 : B2;
G1 = (G1 >= 0x100) ? 0xFF :
(G1 <= 0) ? 0 : G1;
G2 = (G2 >= 0x100) ? 0xFF :
(G2 <= 0) ? 0 : G2;
dest[j] = get_colour (hps, R1, G1, B1);
dest[j+1] = get_colour (hps, R2, G2, B2);
}
WinReleasePS (hps);
}
static BYTE get_colour (HPS hps, USHORT r, USHORT g, USHORT b)
{
ULONG i;
LONG d;
LONG rgb;
rgb = (LONG)((r * 0x10000) + (g * 0x100) + b);
rgb = GpiQueryNearestColor (hps, 0, rgb);
d = GpiQueryColorIndex (hps, 0, rgb);
return (BYTE)(d & 0xff);
}