[[ header START ]]

Welcome to OS2.GURU site! (eComStation.RU)

Select your language: Russian English Deutch Spanish Italian Portuguese Czech Polish French

Frequently asked questions and answers:
telegram

Форум обсуждение

telegram

Send message

telegram

[ +7-981-8529467 (Санкт-Петербург)

telegram

t.me/os2_guru

eComStation.RU


ru · en · de · es · it · pt · cz · pl · fr
OS/2 - это совершенно другая операционная система для PC (ArcaOS, eComStation, IBM OS/2 Warp)
Программы, новости, статьи, поддержка пользователей, оборудование, вопросы и ответы.
 
[Что такое OS/2?  Новости  Установка  Обновление  
 
 
Применение  Будущее  Сообщество  Проекты  

[Как заработать в OS/2?

Как купить OS/2 дискету?

Идеи для фанатов OS/2

*

(Карта сайта)

 
 
[[ head-3-search ]]

Списки протестированного OS/2 оборудования

[[ head-3-search END ]]

 
Обновление

 
Программы

 
(Санкт-Петербург)

 
Преимущества (1)

 
Разработчику (1)

 
(Пайпы программ)

 
Компании: (1)

 
История (1):

 
(Бонусы)

 
Советы:

 
(Барьеры и решения)

 
Технологии: (1)

 
(Применение в науке, лаборатории, ..)

 

 
Готовые решения:

 
Новая eComStation:

 
Будущее: (1)

 
(Ссылки на другие сайты)

 
(Картинка дня)

 
Артефакты OS/2

 
Гаджеты

eCo Software Developer Connection


About DevCon
Subscription to DevCon
Budget of DevCon
FAQ


Roadmap
eCo Software runtime
eCo Software toolkit
Contacts

  Вы можете перевести эту страничку на русский язык
Присылайте готовый текст через веб-форму

/ ecomedia library / description

ECOMEDIA.DLL v 2.0

(c) eCo Software
2008/02/28

Usage of new functions of ecomedia.dll, added in version 2.0.

The most important feature of version 2.0 of ecomedia.dll is a new bitmap format: BITMAP2. The most important features BITMAP2 are:

  • 1. Transparency (alpha channel)
  • 2. Safety (Gpi2CreateBitmap, Gpi2ScaleBitmap, Gpi2ReadPng etc. will allways create new BITMAP2 handle and will newer return existing BITMAP2 handle)
  • 3. Using high memory (above 512MB)

Note: at this time BITMAP2 supports only truecolor: RGB (24-bit) and RGBA (32-bit) color depth. To tell the truth, on the modern system 2, 4, 8, or 16 bit depth is not really essential.

New data types:

BITMAP2HEADER - header of BITMAP2 structure:

struct _BITMAP2HEADER;
typedef struct _BITMAP2HEADER BITMAP2HEADER, *PBITMAP2HEADER;
struct _BITMAP2HEADER
{
    ULONG   cb;         // bytes count
    USHORT  usCx;       // bitmmap width
    USHORT  usCy;       // bitmap height
    BYTE    cChannels;  // Number of color channels: 3 - RGB, 4 - RGBA
    BYTE    cBits;      // Bits per pixel: 8 is the only valid value for now
};
BITMAP2:

struct _BITMAP2 - BITMAP2 structure:

typedef struct _BITMAP2 BITMAP2, *PBITMAP2;
struct _BITMAP2
{
    ULONG   cb;             // bytes count
    USHORT  usCx;           // bitmmap width
    USHORT  usCy;           // bitmap height
    BYTE    cChannels;      // Number of color channels: 3 - RGB, 4 - RGBA
    BYTE    cBits;          // Bits per pixel: 8 is the only valid value for now
    BYTE    cBitmapData[1]; // Bitmap data (each row padded to 4-byte alignment)
};

HBITMAP2 - BITMAP2 handle

typedef LHANDLE HBITMAP2; // New bitmap handle

New flags used by BITMAP2 functions:

#define FL_STRIPALPHA   0x01    // "Ignore alpha channel"
#define FL_PROCESSALPHA 0x02    // Process alpha by mixing image with specified background color
#define FL_COPYALPHA    0x04    // Use bKGD PNG chunk to determine background color.
#define FL_USEBKGD      0x08    // Use bKGD PNG chunk to determine background color.

Functions for BITMAP2:

Using BITMAP2 bitmaps

First of all, you need to create a BITMAP2. To do it, function Gpi2CreateBitmap() is used. It's syntax is really simple:

HBITMAP2 APIENTRY Gpi2CreateBitmap(USHORT usCx, USHORT usCy, // Bitmap dimension
   BYTE cChannels,           // Number of channels. In this version valid values are 3 (RGB) and 4 (RGBA)
   BYTE cBits,               // Bits per channel. In this version the only valid value is 8
   PBYTE pbBitmapData);      // Bitmap data used for initialization. If NULL, bitmap is not initialized after creation.

Returns: NULLHANDLE - error occured. Gpi2GetLastError() will return error code;
	 Oher - new bitmap handle;

**********************************************************
*** Example of creating new bitmap with initialization ***
**********************************************************

PBYTE    cBitmapArray;    // Bitmap data buffer
ULONG    row, col;        // Temporary variables used in a loop
HBITMAP2 hbm2;            // BITMAP2 handle
const ULONG ulWidth=32;   // Bitmap width
const ULONG ulHeight=32;  // Bitmap height
const ULONG ulChannels=4; // 4 cannels = RGBA

// Allocate memory for bitmap data
if (!DosAllocMem((PPVOID)&cBitmapArray, ulWidth*ulHeight*ulChannels, PAG_COMMIT|PAG_READ|PAG_WRITE))) 
{
   // Fill bitmap data with half-transparent bright yellow color
   for (row=0; row

If bitmap was not initialized with data during creation, you have to use Gpi2SetBitmapBits() function to initialize it. This function could be also used to fill the bitmap (some rows if it) with different data. The syntax is:

BOOL APIENTRY Gpi2SetBitmapBits(HBITMAP2 hbitmap2, // BITMAP2 handle
   LONG lScanStart,   // first scanline (0 means the bottom one)
   LONG lScans,       // number of scanlines to be filled
   PBYTE pbBuffer);   // address of the buffer, containing data to be copied int the bitmap

Returns: TRUE - function completed successfuly
         FALSE - error occured. Gpi2GetLastError() will return error code;

**********************************************************
***   Example of filling part of a bitmap with data   ***
**********************************************************

// Let's suppose that the code followed the first example

if (!DosAllocMem((PPVOID)&cBitmapArray, ulWidth*ulHeight/2*ulChannels, PAG_COMMIT|PAG_READ|PAG_WRITE))) // Allocate memory for bitmap data (half height)
{
   // Fill bitmap data (bottom half) with non-transparent bright magenta color
   for (row=0; row

To get either bitmap information (header) or bitmap data, Gpi2QueryBitmapInfo() and Gpi2QueryBitmapBits() should be used. It will be useful to process BITMAP2 data directly. Syntax:

BOOL APIENTRY Gpi2QueryBitmapInfo(HBITMAP2 hbitmap2,            // BITMAP2 handle
                                  PBITMAP2HEADER pbmp2header);  // Pointer to BITMAP2HEADER structure, 
                                                                // where bitmap information will be placed

Returns: TRUE - function completed successfuly
         FALSE - error occured. Gpi2GetLastError() will return error code;

BOOL APIENTRY Gpi2QueryBitmapBits(HBITMAP2 hbitmap2, // BITMAP2 handle
                                  LONG lScanStart,   // First scanline
                                  LONG lScans,       // number of scanlines
                                  PBYTE pbBuffer);   // memory buffer where bitmap data will be copied

Returns: TRUE - function completed successfuly
         FALSE - error occured. Gpi2GetLastError() will return error code;

**********************************************************
*** Example of copying bitmap by using                 ***
*** Gpi2QueryBitmapInfo() and Gpi2QueryBitmapBits()    ***
**********************************************************

BITMAP2HEADER bmp2header;
HBITMAP2      hbm2new;

// Let's suppose that here we have code from the first example
...


if (Gpi2QueryBitmapBits(hbm2, &bmp2header) // Query bitmap data
   // Allocate memory for new bitmap data
   if (!DosAllocMem((PPVOID)&cBitmapArray, bmp2header.usCx*bmp2header.usCy*bmp2header.cChannels, PAG_COMMIT|PAG_READ|PAG_WRITE))) 
   {
      	Gpi2QueryBitmapBits(hbm2, 0, bmp2header.usCy, &cBitmapArray); // Copy bitmap data
	      // Create bitmap and initialize it with copied bitmap data
       hbm2new = Gpi2CreateBitmap(bmp2header.usCx, bmp2header.usCy, bmp2header.cChannels, bmp2header.cBits, cBitmapArray); 
   }

**********************************************************
***                 End of the example                 ***
**********************************************************

Okay! The code above was just an example of using some calls. To tell the truth, its absolutely useless, 'cause ecomedia.dll contains a function for copying bitmaps, which works faster than the code above: Gpi2CopyBitmap(). It's syntax:

HBITMAP2 APIENTRY Gpi2CopyBitmap(HBITMAP2 hbitmap2); // BITMAP2 handle to be copied

Returns: NULLHANDLE - error occured. Gpi2GetLastError() will return error code;
	 Other - new bitmap handle;

Pretty simple, right? I don't think it needs an example of using it. Another useful function is Gpi2CropBitmap(). Yeah, it allows you to crop bitmap. Its syntaxs also simple:

HBITMAP2 APIENTRY Gpi2CropBitmap(HBITMAP2 hbitmap2, // BITMAP2 handle to be cropped
                                 PRECTL prcl);      // pointer to RECTL structure, containg the rectangle inside hbitmap2 to crop
 
Returns: NULLHANDLE - error occured. Gpi2GetLastError() will return error code;
	 Other - cropped bitmap handle;

And now... You know how to create and process bitmap. The only thing is left is bitmap output. There are two functions in ecomedia.dll for tis task:
Gpi2BitBlt() - to blit one BITMAP2 into another one, and Gpi2DrawBitmap() - to draw bitmap into a presentation space. Their syntax:

BOOL APIENTRY Gpi2BitBlt(HBITMAP2 hbm2Target, // Target bitmap handle
   HBITMAP2 hbm2Source, // Source bitmap handle
   LONG lCount,         // Number of points (from 1 to 3) in the aptlPoints
   PPOINTL aptlPoints,  // array of POINTL structures, describing source and target blitting areas
   ULONG ulBckgColor,   // Background color. Used only if source bitmap have transparent areas (alpha channel) and FL_PROCESSALPHA flag is specified.
   ULONG flOptions);    // Bitmap flags. Valid flags are FL_STRIPALPHA, FL_PROCESSALPHA, FL_COPYALPHA

Returns: TRUE - function completed successfuly
         FALSE - error occured. Gpi2GetLastError() will return error code;

BOOL APIENTRY Gpi2DrawBitmap(HPS hpsTarget,       // Target presentation space handle
   HBITMAP2 hbm2Source, // Source bitmap handle
   LONG lCount,         // Number of points (from 1 to 3) in the aptlPoints
   PPOINTL aptlPoints); // array of POINTL structures, describing source and target blitting areas

Returns: TRUE - function completed successfuly
         FALSE - error occured. Gpi2GetLastError() will return error code;

Both unlike GpiBitBlt() and WinDrawBitmap() calls, Gpi2DrawBitmap() and Gpi2BitBlt() are accept only 3 points, so no scaling is preformed. To scale bitmap Gpi2ScaleBitmap2() is used. Its syntax is:

	 
HBITMAP2 APIENTRY Gpi2ScaleBitmap2(HBITMAP2 hbitmap2, // Handle of BITMAP2 to be scaled
                                   ULONG width,       // New bitmap width
                                   ULONG height,      // New bitmap height
                                   BOOL bKeep);       // Keep aspect ratio flag

Returns: NULLHANDLE - error occured. Gpi2GetLastError() will return error code;
	 Other - scaled bitmap handle;

Note: there is also Gpi2ScaleBitmap() function, which works with standard OS/2 BITMAP (not BITMAP2) format. It is left only for backwards compatibility and being unsafe is DEPRECATED!

Of course, after bitmap was used and is not needed anymore, it must be deleted. Use Gpi2DeleteBitmap() function to do it. It's syntax is obvious:

BOOL APIENTRY Gpi2DeleteBitmap(HBITMAP2 hbitmap2); // Handle of BITMAP2 to be deleted
Returns: TRUE - function completed successfuly
         FALSE - error occured. Gpi2GetLastError() will return error code;

Okay! Let's see, how we can use those functions.

**********************************************************
*** Example of drawing bitmap by using                 ***
*** Gpi2BitBlt(), Gpi2DrawBitmap(), Gpi2DeleteBitmap() ***
*** and Gpi2ScaleBitmap2() functions                   ***
**********************************************************

// Let's suppose that this is a part of the window procedure...

HBITMAP2 hbm2scaled;
POINTL   aptlPoints[3];
RECTL    rcl;
HPS      hps;


switch (msg)
{

...

   case WM_PAINT:
      hps=WinBeginPaint(hps, 0L, &rcl);
      if (hps)
      {

         // Let's suppose that here we have code from the second example
         ...

        hbm2scaled=Gpi2ScaleBitmap(hbm2, ulWidth/2, ulHeight/2, FALSE); // Shrink bitmap
        if (hbm2Scaled)
        {
            // Lower-left corner in the source bitmap
            aptlPoints[0].x=5;
            aptlPoints[0].y=5;

            // Upper-right corner in the source bitmap
            aptlPoints[1].x=ulWidth/2-5;
            aptlPoints[1].y=ulHeight/2-5;

            aptlPoints[2].x=1;
            aptlPoints[2].y=1;
            if (Gpi2BitBlt(hbm2, hbm2scaled, 3, aptlPoints, 0L, 0L))
            {
               // Let's suppose, that the window (hwnd) and the bitmap (hbm2) have the same size,
               // so, let's copy appropriate part of the bitmap to the window's update rectangle
               aptlPoints[0].x=rcl.xLeft;
               aptlPoints[0].y=rcl.yBottom;
               aptlPoints[1].x=rcl.xRght;
               aptlPoints[1].y=rcl.yTop;
               aptlPoints[2].x=rcl.xLeft;
               aptlPoints[2].y=rcl.yBottom;
               Gpi2DrawBitmap(hps, hbm2, 3, aptlPoints);
            }
            // Yeah! Delete the bitmap, 'cause we don't need it anymore
            Gpi2DeleteBitmap(hbm2Scaled); 
         }           
         WinEndPaint(hps);

         Gpi2DeleteBitmap(hbm2); // We don't need this one as well!
      }
      break;  

...

}

return WinDefWindowProc(hwnd, msg, mp1, mp2);

**********************************************************
***                 End of the example                 ***
**********************************************************

Switching between old (OS/2 BITMAP) and new (BITMAP2) formats

Well, as you could see, everything is really simple. Those, who have experience in GPI programming will learn using that Gpi2* stuff without any problem.

And, if you already have an application, which uses GPI for drawing grapics, don't hesitate to switch it to Gpi2* calls. To simplify this task, there are two special functions in ecomedia.dll: Gpi2Bitmap2FromBitmap() and Gpi2BitmapFromBitmap2. Yeah! They doing just what they say: converting BITMAP2 format to standard OS/2 BITMAP and back. The syntax is:

HBITMAP2 APIENTRY Gpi2Bitmap2FromBitmap(HBITMAP hbmp); // Source BITMAP handle

Returns: NULLHANDLE - error occured. Gpi2GetLastError() will return error code;
	 Other - new converted BITMAP2 handle;

HBITMAP APIENTRY Gpi2BitmapFromBitmap2(HBITMAP2 hbmp2,  // Source BITMAP handle
   ULONG ulColor,   // Background color. Used only if source bitmap have transparent areas (alpha channel) and FL_PROCESSALPHA flag is specified.
   ULONG flFlags);  // Flags, which determine, how alpha channel will be treated. Valid flags are: FL_STRIPALPHA, FL_PROCESSALPHA, FL_COPYALPHA.

Returns: NULLHANDLE - error occured. Gpi2GetLastError() will return error code;
	 Other - new converted BITMAP handle;

I think, using those functions is clear enough, so there is no need to publish examples of using those functions.

Instead, let's talk about two really useful features of ecomedia.dll, which will help you to develop nice mordern apllications: working with OS/2 bitmap data formats (icons/pointers/bitmaps) and working with portable network graphics (PNG) data formats:

Working with OS/2 Icon/Pointer/Bitmap data files

There are no functions for parsing OS/2 Icon/Pointer/Bitmap data structures in OS/2 GPI/PM. WinLoadBitmap()/WinLoadPointer() functions processing those structures internally giving you BITMAP/POINTER handle. So, if the file you are working with is an array, you are unable to choose which image of the array you need.

There are three functions in ecomedia.dll v2 to process OS/2 Icons/Pointers/Bitmaps: Gpi2GetIconData(), Gpi2ParseIconInfo() and Gpi2ReadBitmap().

Gpi2ReadBitmap() is the low-level function which used to parse the OS/2 icon data. Its syntax:

HBITMAP2 APIENTRY Gpi2ReadBitmap(PVOID pIconData,            // OS/2 Icon data
   PULONG pulCx, PULONG pulCy, // Image size
   USHORT usBitCount,          // Image bit depth
   ULONG ulBckgColor,          // Background color. Used only if source icon/pointer have transparent areas and FL_PROCESSALPHA flag is specified.
   ULONG ulColor0,             // Image color (0). Used only for monochrome (black-and-white) bitmaps
   ULONG ulColor1,             // Image color (1). Used only for monochrome (black-and-white) bitmaps
   ULONG flOptions);           // Icon processing flags

Returns: NULLHANDLE - error occured. Gpi2GetLastError() will return error code;
	 Other - BITMAP2 handle;

pIconData: pointer to raw OS/2 icon data. You can get it by reading OS/2 Icon/Pointer/Bitmap from the file or from the resource (using DosLoadResource() function).

pulCx, pulCy: pointer to ULONG variables which on input contain desired image size. If pIconData contains a single image, it will be ignored. If pIconData is a bitmap array, it will be searched to find an image which best fits desired resolution. The decision, which image fits the best is taken this way:

  • If there is an image with the same resolution, it is considered to be the best.
  • Otherwise, if there are images larger, than desired, the smallest of them is considered to be the best.
  • Otherwise, the largest image is considered to be the best.

usBitCount: desired bit depth. If there are more that one image have resolution, which considered to be the best, usBitCount is taken in account:

  • If there is an image with the same bit count, it is considered to be the best.
  • Otherwise, if there are images with bigger bit depth, than desired, the image with smallest bit depth is considered to be the best.
  • Otherwise, the image with larger bit depth is considered to be the best.

ulBckgColor: used if the image is either a pointer or an icon and contains transparent areas, and FL_PROCESSALPHA flag specified. See flOptions for more detailed info.

ulColor0, ulColor1: Colors used for monochrome (1bps) bitmaps. ulColor0 is used for pixels which are set to 0 and ulColor1 is used for pixels, which are set to 1.

flOptions: bit flags used to specify how to process image. The only valid flag for now is: FL_PROCESSALPHA. This flag is meaningful only if the image is either a pointer or an icon and contains transparent or inverted areas:

  • If this flag is specified, RGB (true color without alpha channel) BITMAP2 is created. Transparent areas are filled with ulBckgColor color and inverted areas are filled with inverted ulBckgColor.
  • If this flag is not specified, RGBA (true color with alpha channel) bitmap is created. Transparent areas are left transparent (alpha = 0) and inverted areas are ignored (also become transparent).

Working with PNG data files

ECOMEDIA.DLL also provides function to work with portable network graphics (PNG) data file format: Gpi2ReadPng(). Here is the syntax:

HBITMAP2 APIENTRY Gpi2ReadPng(PBYTE pPngData,          // PNG data
   ULONG ulBackgroundColor, // Background color (see below)
   ULONG flOptions); // PNG processing flag (see below).

Returns: NULLHANDLE - error occured. Gpi2GetLastError() will return error code;
	 Other - BITMAP2 handle;

Used only if source PNG have transparent areas (alpha channel or transparency chunk) and FL_PROCESSALPHA flag is specified and FL_USEBKGD flag is not specified or no PNG contains no bKGD chunk.

This function reads and renders PNG data specified by pPngData, and returns BITMAP2 handle. You can obtain PNG data by reading PNG file or by loading it from the resources (using DosLoadResource() function).

flOptions parameter used to specify how to process transparent areas in the PNG (if either alpha channel or tRNS chunk present).

Valid options are:

  • FL_STRIPALPHA - ignore alpha channel/transparency;
  • FL_PROCESSALPHA - render PNG using ulBackgroundColor parameter as a background color.
  • FL_USEBKGD - use bKGD chunk instead of ulBackgroundColor as a background color. Ignored of FL_PROCESSALPHA is not specified or bKGD chunk is not present.

When PNG has transparency (alpha channel or tRNS chunk) and neither FL_STRIPALPHA nor FL_PROCESSALPHA flag is specified, RGBA (32-bit) BITMAP2 is created. Otherwise, RGB (24-bit) BOTMAP2 is created.

Special functions

There are three special functions, added to ECOMEDIA.DLL v2.0:

Gpi2GetVersion(), Gpi2GetVersionString() - allows you to check the library version. Syntax:
VOID APIENTRY Gpi2GetVersion(PULONG pulMajor,  // Major version number
                             PULONG pulMinor); // Minor version number

returns: nothing

USHORT APIENTRY Gpi2GetVersionString(PSZ pszBuffer,    // Buffer, where string, containing version number will be placed
                                     USHORT cbBufLen); // pszBuffer length

returns: number of characters copied to pszBuffer

Gpi2GetLastError(): returns error code of the last failed Gpi2* function. Syntax:

APIRET APIENTRY Gpi2GetLastError();

returns: error code

THE MOST IMPORTANT PART

Examine PNGTEST example carefuly to see usage of all the functions, described in this document. This is the best and easiest way to learn how to use new features of ECOMEDIA.DLL v2.0!

 

 
Обучение новичков

Списки протестированного OS/2 оборудования

 
Статьи


   
  Почему eComStation?
Возможности
Особенности
Применение
Ролики и скриншоты
   eComStation для
для бизнесменов
для студентов и инженеров
для продавцов компьютеров
сообщество пользователей
   Разработчик
Распространить программу
Описание API, библиотеки
Начать новый проект
Конкурсы
   Программы
Он-лайн каталог
Выбрать через eCo Market
   Служба поддержки
Отправить вопрос
Купить eComStation
Вопросы и ответы
Обучение новичков
 
 
© 2001 - 2021 eCo Software, All rights reserved
Сибирский Медведь технологическая компания
eComStation Serenity Systems International • OS/2 Warp IBM Corporation • ArcaOS Arca Noae