⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misc.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
//
// Permedia3 Sample Display Driver
// misc.c
//
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
//
// This module contains various utility routines that don't fit into any
// of the other source modules.

#include "pch.h"  // Precompiled header support.
#include "debug.h"
#include "struct.h"
#include "proto.h"

// Dumb little helper macro.

#define TwoToThe(a) (1 << (a))

// These tables allows us an easy conversion from a GDI format value to a
// useable PERM3_FORMAT structure. We only use these if we are not given an
// XLATEOBJ to extract mask info from.

// The masks and palettes are from the Platform Builder documentation on
// display formats.

static const ULONG l_Perm3FormatLookup1BppPalette[] = {
  0x00000000, // 0 = Black
  0x00FFFFFF  // 1 = White
};

static const ULONG l_Perm3FormatLookup2BppPalette[] = {
  0x00000000, // 0 = Black
  0x00808080, // 1 = Dark gray
  0x00C0C0C0, // 2 = Light gray
  0x00FFFFFF  // 3 = White
};

static const ULONG l_Perm3FormatLookup4BppPalette[] = {
  0x00000000, // 0 = Black
  0x00000080, // 1 = Dark red
  0x000000FF, // 2 = Red
  0x00008000, // 3 = Dark green
  0x00008080, // 4 = Dark yellow
  0x0000FF00, // 5 = Green
  0x0000FFFF, // 6 = Yellow
  0x00800000, // 7 = Dark blue
  0x00800080, // 8 = Dark purple
  0x00808000, // 9 = Dark teal
  0x00808080, // 10 = Dark gray
  0x00C0C0C0, // 11 = Light gray
  0x00FF0000, // 12 = Blue
  0x00FF00FF, // 13 = Purple
  0x00FFFF00, // 14 = Teal
  0x00FFFFFF  // 15 = White
};

static const ULONG l_Perm3FormatLookup8BppPalette[] = {
  0x00000000, // 0 = Black
  0x00000080, // 1 = Dark red
  0x000000FF, // 2 = Red
  0x00008000, // 3 = Dark green
  0x00008080, // 4 = Dark yellow
  0x0000FF00, // 5 = Green
  0x0000FFFF, // 6 = Yellow
  0x00800000, // 7 = Dark blue
  0x00800080, // 8 = Dark purple
  0x00808000, // 9 = Dark teal
  0x00808080, // 10 = Dark gray
  0x00C0C0C0, // 11 = Light gray
  0x00FF0000, // 12 = Blue
  0x00FF00FF, // 13 = Purple
  0x00FFFF00, // 14 = Teal
  0x00FFFFFF  // 15 = White
   // !TODO! what's the rest of the standard windows 8bpp palette?
};

static const ULONG l_Perm3FormatLookupMasks[][4] = {
  // Red        Green       Blue        Alpha
  { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, // NULL format
  { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, // 565
  { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }  // 888
};

static const PERM3_FORMAT l_Perm3FormatLookup[] = {

  { 0,            0, l_Perm3FormatLookupMasks[0],    FALSE, 0 },
  { FOURCC_PAL,   1, l_Perm3FormatLookup1BppPalette, FALSE, 0 },
  { FOURCC_PAL,   4, l_Perm3FormatLookup4BppPalette, FALSE, 0 },
  { FOURCC_PAL,   8, l_Perm3FormatLookup8BppPalette, FALSE, 0 },
  { FOURCC_RGB,  16, l_Perm3FormatLookupMasks[1],    FALSE, 0 },
  { FOURCC_RGB,  24, l_Perm3FormatLookupMasks[2],    FALSE, 0 },
  { FOURCC_RGB,  32, l_Perm3FormatLookupMasks[2],    FALSE, 0 },
  { 0,            0, l_Perm3FormatLookupMasks[0],    FALSE, 0 },
  { 0,            0, l_Perm3FormatLookupMasks[0],    FALSE, 0 },
  { FOURCC_PAL,   2, l_Perm3FormatLookup2BppPalette, FALSE, 0 }
};
static const ULONG l_NumPerm3FormatLookup = sizeof(l_Perm3FormatLookup) / sizeof(PERM3_FORMAT);

// We also keep cached PERM3_FORMAT structures that pertain to the GDI RGB and
// BGR formats.

static const ULONG l_RGBMasks[4] = {
  0x000000FF,
  0x0000FF00,
  0x00FF0000,
  0x00000000
};

static const PERM3_FORMAT l_RGBFormat = {
  FOURCC_RGB,
  24,
  l_RGBMasks
};

static const ULONG l_BGRMasks[4] = {
  0x00FF0000,
  0x0000FF00,
  0x000000FF,
  0x00000000
};

static const PERM3_FORMAT l_BGRFormat = {
  FOURCC_RGB,
  24,
  l_BGRMasks
};

// Internal prototypes. These functions are not exposed outside this module.

static void
LoadPaletteMasks(
  PERM3_FORMAT * Format,
  XLATEOBJ     * Xlate,
  ULONG          Fields,
  ULONG          Entries
  );

ULONG
GdiFormatToBPP(
  ULONG GdiFormat
  )
{
  // GdiFormatToBPP
  // This function converts a GDI format value to an integer bits per
  // pixel value. No Enter/Exit semantics as this function should be
  // inlined.

  // Local constants. 

  // This lookup table is derived from the BMF_*BPP macros in the 
  // winddi.h header file. 0s are set in the undefined format values.

  const ULONG Lookup[] = { 0, 1, 4, 8, 16, 24, 32, 0, 0, 2 };
  const ULONG NumLookup = sizeof(Lookup) / sizeof(ULONG);

  // Check parameters.

  Assert(GdiFormat < NumLookup);

  return (Lookup[GdiFormat]);
}

ULONG
BPPToGdiFormat(
  ULONG BitsPerPixel
  )
{
  // BPPToGdiFormat
  // This function converts a bits per pixel integer to a GDI format
  // value. No Enter/Exit semantics are used as this function should be
  // inlined.

  // Local variables.

  ULONG GdiFormat;

  // Check parameters.

  // BitsPerPixel is check implicitly by the code.

  // The BMF_*BPP macros are defined in winddi.h.

  switch (BitsPerPixel) {

  case 1:  GdiFormat = BMF_1BPP;  break;
  case 2:  GdiFormat = BMF_2BPP;  break;
  case 4:  GdiFormat = BMF_4BPP;  break;
  case 8:  GdiFormat = BMF_8BPP;  break;
  case 16: GdiFormat = BMF_16BPP; break;
  case 24: GdiFormat = BMF_24BPP; break;
  case 32: GdiFormat = BMF_32BPP; break;

  default:

    Error(L"Unknown BitsPerPixel = %d.\n", BitsPerPixel);
    GdiFormat = 0;
    break;
  }

  return GdiFormat;
}

const PERM3_FORMAT *
GdiFormatToPerm3Format(
  ULONG GdiFormat
  )
{
  // GdiFormatToPerm3Format
  // This function returns a filled out PERM3_FORMAT structure (from a table)
  // coresponding to the given GDI format value. No Enter/Exit semantics
  // for inlined functions.

  // Check parameters.

  Assert(GdiFormat < l_NumPerm3FormatLookup);

  return (&l_Perm3FormatLookup[GdiFormat]);
}

void
SurfobjToPerm3Surface(
  PERM3_SURFACE * Perm3Surface,
  SURFOBJ       * Surfobj,
  XLATEOBJ      * Xlate,
  BOOL            Source
  )
{
  // SurfobjToPerm3Surface
  // This function converts a GDI SURFOBJ into a PERM3_SURFACE structure. We
  // will be able to use the pointer we stored in the SURFOBJ for video
  // memory allocations. Other times, when we haven't seen the surface
  // before, we will need to fill out the Perm3Surface by hand.

  // We'll use the Xlateobj to get our format detail if it's avialable.
  // Otherwise, we have sensible defualts available through
  // GdiFormatToPerm3Format.

  // Local variables.

  PERM3_SURFACE * Dhsurf;
  PERM3_FORMAT  * Format;

  // Check parameters.

  Assert(sizeof(SIZE) == sizeof(SIZEL));

  // !TODO!

  Enter(L"SurfobjToPerm3Surface");

  Dhsurf = (PERM3_SURFACE *)(Surfobj->dhsurf);

  if (Dhsurf != NULL) {

    // If there is a Dhsurf, it mean's that this is a "device managed" surface.
    // It was created by DrvCreateDeviceBitmap, and the PERM3_SURFACE data
    // is all already available.

    memcpy(Perm3Surface,
           Dhsurf,
           sizeof(PERM3_SURFACE));
  }
  else {

    // GDI created this suface on it's own. Do it the hard way.

    Perm3Surface->Ptr = Surfobj->pvScan0;
 
    // We copy from a SIZEL to a SIZE. This is protected by the assert above.

    memcpy(&Perm3Surface->Size,
           &Surfobj->sizlBitmap,
           sizeof(SIZE));

    Perm3Surface->Stride = Surfobj->lDelta;

    Perm3Surface->Type = SystemMemory;

    // Now, the format may be given by the XLATEOBJ, in which case we copy
    // it out. If not, we rely on GdiFormatToPerm3Format to provide a
    // reasonable default.

    if (Xlate && Xlate->flXlate != XO_TRIVIAL) {

      switch (Source ? Xlate->iSrcType : Xlate->iDstType) {
      case PAL_INDEXED:

        Format = (PERM3_FORMAT *)SystemAlloc(sizeof(PERM3_FORMAT));
        if (Format != NULL) {
            
          Format->BitsPerPixel = GdiFormatToBPP(Surfobj->iBitmapFormat);  
          Format->FourCC = FOURCC_PAL;

          // The XLATEOBJ identifies a number of special case translations,
          // generally, we need only deal with those special cases when
          // we are looking for a palette.

          if ((Xlate->flXlate == XO_TABLE && Source) ||
              (Xlate->flXlate == XO_TO_MONO && Format->BitsPerPixel == 1)) {

            // GDI has already prepared a lookup table. Use it.

            Format->Palette = Xlate->pulXlate;
            Format->FreePaletteMasks = FALSE;
          }
          else {
            LoadPaletteMasks(Format,
                             Xlate,
                             (Source) ? XO_SRCPALETTE : XO_DESTPALETTE, 
                             TwoToThe(Format->BitsPerPixel));
          }

          Perm3Surface->FreeFormat = TRUE;
          Perm3Surface->Format = (const FORMAT *)Format;
        }
        else {
          Error(L"System memory allocation failure.\n");
        }
        break;

      case PAL_BITFIELDS:

        Format = (PERM3_FORMAT *)SystemAlloc(sizeof(PERM3_FORMAT));
        if (Format != NULL) {
            
          Format->BitsPerPixel = GdiFormatToBPP(Surfobj->iBitmapFormat);  
          Format->FourCC = FOURCC_RGB;

          LoadPaletteMasks(Format,
                           Xlate,
                           (Source) ? XO_SRCBITFIELDS : XO_DESTBITFIELDS, 
                           4);

          Perm3Surface->FreeFormat = TRUE;
          Perm3Surface->Format = (const FORMAT *)Format;
        }
        else {
          Error(L"System memory allocation failure.\n");
        } 
        break;

      case PAL_RGB:

        // We have a cached PERM3_FORMAT for RGB.

        Perm3Surface->FreeFormat = FALSE;
        Perm3Surface->Format = (const FORMAT *)&l_RGBFormat;
        break;

      case PAL_BGR:

        // We have a cached PERM3_FORMAT for BGR.

        Perm3Surface->FreeFormat = FALSE;
        Perm3Surface->Format = (const FORMAT *)&l_BGRFormat;
        break;

      default:

        Error(L"Unknown surface type in Xlateobj.\n");
        break;
      }
    }
    else {

      Perm3Surface->FreeFormat = FALSE;
      Perm3Surface->Format = (const FORMAT *)GdiFormatToPerm3Format(Surfobj->iBitmapFormat);
    }
  }

  Exit(L"SurfobjToPerm3Surface");
}

void
FreeSurfobjDerivedPerm3Surface(
  PERM3_SURFACE * Perm3Surface
  )
{
  // FreeSurfobjDerivedPerm3Surface
  // This function is used to cleanup the Perm3Surface structures created
  // by SurfobjToPerm3Surface. It handles freeing the format and masks
  // if necessary.

  // Local variables.

  PERM3_FORMAT * Format;

  // Check parameters.

  // !TODO!

  Enter(L"FreeSurfobjDerivedPerm3Surface");

  Format = (PERM3_FORMAT *)(Perm3Surface->Format);

  if (Format->FreePaletteMasks) {

    // Again, note that the fact that Masks and Palette are a union means that
    // this also handles paletted formats.

    SystemFree((ULONG *)Format->Masks);
  }

  if (Perm3Surface->FreeFormat) {

    SystemFree(Format);
  }

  Exit(L"FreeSurfobjDerivedPerm3Surface");
}

const PERM3_FORMAT *
GetRGBFormat()
{
  // GetRGBFormat
  // This function returns a PERM3_FORMAT coresponding to GDI's conception
  // of a 24 bpp, xRGB color format, which we happen to have cached locally.
  // No Enter/Exit semantics are used for inlined functions.

  return (&l_RGBFormat);
}

const PERM3_FORMAT *
GetBGRFormat()
{
  // GetBGRFormat
  // This function returns a PERM3_FORMAT coresponding to GDI's conception
  // of a 24 bpp, xBGR color format, which we happen to have cached locally.
  // No Enter/Exit semantics are used for inlined functions.

  return (&l_BGRFormat);
}

ULONG
PackXY(
  ULONG X,
  ULONG Y
  )
{
  // PackXY
  // Many Permedia3 registers require an (x,y) coordinate pair packed into
  // a single 32 bit value. This function does just that. No Enter/Exit
  // semantics for inlined functions.

  return ((X & 0xFFFF) | ((Y & 0xFFFF) << 16));
} 

ULONG
Abs(
  LONG Value
  )
{
  // Abs
  // Return the absolute value of a signed value in an unsigned value. No
  // Enter/Exit semantics for inlined code.

  return ((ULONG)(Value > 0 ? Value : -Value));
}

void
LoadPaletteMasks(
  PERM3_FORMAT * Format,
  XLATEOBJ     * Xlate,
  ULONG          Fields,
  ULONG          Entries
  )
{
  // LoadPaletteMasks
  // This function extracts the Mask/Palette data from an XLATEOBJ. It assumes
  // that at some later time, the Palette/Mask pointer will be freed. It
  // sets a flag to enfore this.

  // Local variables.

  ULONG * Masks;

  // Check parameters.

  // !TODO!

  // Note that Masks and Palette members of the FORMAT struct are in a union.
  // Therefore, we can load both just by refering to Masks.

  Enter(L"LoadPaletteMasks");

  Masks = (ULONG *)SystemAlloc(sizeof(ULONG) * Entries);
  if (Masks != NULL) {

    if (!XLATEOBJ_cGetPalette(Xlate, 
                              Fields, 
                              Entries, 
                              Masks) == 0) {

      Format->FreePaletteMasks = TRUE;
      Format->Masks = Masks;
    }
    else {
      Error(L"XLATEOBJ failure.\n");
    }
  }
  else {
    Error(L"System memory allocation failure.\n");
  }

  Exit(L"LoadPaletteMasks");
}

ULONG
GetSizeofPaletteMasks(
  const PERM3_FORMAT * Format
  )
{
  // GetSizeofPaletteMasks
  // This function computes the number of bytes there should be in the
  // palette/mask union array for a given format.

  // Local variables.

  ULONG SizeofPaletteMasks;

  // Check parameters.

  // !TODO!

  Enter(L"GetSizeofPaletteMasks");

  if (Format->FourCC == FOURCC_RGB) {

    SizeofPaletteMasks = sizeof(ULONG) * 4;
  }
  else if (Format->FourCC == FOURCC_PAL) {

    SizeofPaletteMasks = TwoToThe(Format->BitsPerPixel);
  }
  else {

    Error(L"Unknown FourCC detected.\n");
    SizeofPaletteMasks = 0;
  }

  Exit(L"GetSizeofPaletteMasks");

  return (SizeofPaletteMasks);
}  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -