## _getimage() and _putimage() Functionality in Text Mode

Q123875

    6.00 6.00a 6.00ax 7.00 | 1.00 1.50
    MS-DOS                 | WINDOWS
    kbprg kbcode

    ---------------------------------------------------------------------
    The information in this article applies to:

       The C Run-time (CRT) included with:
         - Microsoft C versions 6.0, 6.0a, and 6.0ax
         - Microsoft C/C++ version 7.0
         - Microsoft Visual C++ for Windows, versions 1.0 and 1.5
    ---------------------------------------------------------------------

    SUMMARY
    =======

    The graphics library that ships with Microsoft C contains the functions
    _getimage() and _putimage() to read and write blocks of video memory. There
    is also a function called _imagesize() that you can use to determine the
    size of a buffer required to store an image. These image functions work
    only in graphics modes. To obtain the functionality of _getimage() and
    _putimage in a text mode, you need to create a pointer to video memory, and
    access video memory directly through this pointer.

    MORE INFORMATION
    ================

    In the MS-DOS environment, video memory begins at segment 0xB000 for
    monochrome text modes and segment 0xB800 for color text modes. Each
    character is represented by two bytes; a byte containing the ASCII value of
    the character to display and an additional byte representing the attributes
    of the character. Attributes supported in monochrome modes include bold and
    underline, while color mode attributes include foreground and background
    color.

    The sample code in this article uses the _FP_SEG and _FP_OFF macros to
    initialize a global pointer to video memory (lpVM). Then it writes text to
    the screen, allocates memory to store a text block, reads a text block from
    the display, and writes that block to a new area of the display.

    Sample Code
    -----------

    /* Compile Options needed: /AL
    */

    #include <dos.h>
    #include <conio.h>
    #include <memory.h>
    #include <malloc.h>
    #include <process.h>
    #include <stdio.h>

    char * lpVM;    // Global pointer to video memory - set in main()

    /* Calculates offset from beginning of video memory to screen position */
    int VidOff(int column, int row)
    {
        return ( ( row * 80 ) + column ) * 2;
    }

    void PutChar(char c, int x, int y)
    {
        *(lpVM+VidOff(x,y)) = c;
    }

    char GetChar(int x, int y)
    {
        return *(lpVM+VidOff(x,y));
    }

    /* Reads block of video memory matching rectangular coordinates
    ** into buffer (buf) note: buf must have been allocated with enough
    ** space for the block.  Similar to graphics.lib function _getimage().
    */
    void ReadBlock( char * buf, int left, int top, int right, int bottom)
    {
        int row, destoffset, vidoffset;
        size_t rowsize;

        rowsize = ( right - left + 1 ) * 2;

        for ( row=top, destoffset=0; row<=bottom; row++,
              destoffset+=rowsize )
        {
            vidoffset = VidOff(left, row);
            memcpy( buf+destoffset, lpVM+vidoffset, rowsize);
        }
    }

    /* Writes contents of buf to video memory matching coordinates.
    ** Similar to graphics.lib function _putimage().
    */
    void WriteBlock( char * buf, int left, int top, int right, int bottom)
    {
        int row, destoffset, vidoffset;
        size_t rowsize;

        rowsize = ( right - left + 1 ) * 2;

        for ( row=top, destoffset=0; row<=bottom; row++,
              destoffset+=rowsize )
        {
            vidoffset = VidOff(left, row);
            memcpy( lpVM+vidoffset, buf+destoffset, rowsize);
        }
    }

    /* Calculates size requires for block of video memory fitting
    ** coordinates and allocates space with malloc. Similar to
    ** graphics.lib function _imagesize(), but actually allocates
    ** the memory.
    */
    void * AllocBlock( int left, int top, int right, int bottom)
    {
        size_t blocksize;

        blocksize = ( ( right - left + 1) * ( bottom - top + 1) ) * 2;

        return malloc( blocksize );
    }

    void main(void)
    {
        int i,j;

        char * buf;

        system( "cls" );              // clear the display

        _FP_SEG( lpVM ) = 0xB800;     // B000 if monochrome
        _FP_OFF( lpVM ) = 0x0000;

        for (i=1; i<20; i++)
        {
              PutChar( '\\', i, i );
              PutChar( '/', 80-i, i );
        }

        buf = AllocBlock( 5, 5, 80, 15 );

        ReadBlock( buf, 5, 5, 80, 15 );

        printf( "Block read. Press \"Enter\" to write block.\n" );

        getch();

        WriteBlock( buf, 5, 10, 80, 20 );

        getch();
        system( "cls" );              // clear the display
    }

    REFERENCES
    ==========

    Programmmer's Guide to PC & PS/2 Video Systems by Richard Wilton (Microsoft
    Press)

    Additional reference words: kbinf 6.00 6.00a 6.00ax 7.00 1.00 1.50
    KBCategory: kbprg kbcode
    KBSubcategory: CRTIss GraphicsIss

Keywords : kb16bitonly
Issue type :
Technology : kbVCsearch kbAudDeveloper kbCRT

Last Reviewed: May 5, 2001 © 2001 Microsoft Corporation. All rights reserved. Terms of Use.