Changeset 5967 for trunk/src


Ignore:
Timestamp:
Jun 11, 2001, 5:57:15 PM (24 years ago)
Author:
sandervl
Message:

Added RGB555 conversion for CreateDIBitmap & SetDIBits

Location:
trunk/src/gdi32
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gdi32/blit.cpp

    r5901 r5967  
    1 /* $Id: blit.cpp,v 1.31 2001-06-03 14:52:46 sandervl Exp $ */
     1/* $Id: blit.cpp,v 1.32 2001-06-11 15:57:15 sandervl Exp $ */
    22
    33/*
     
    142142    switch(info->bmiHeader.biBitCount) {
    143143    case 15:
    144     case 16:
     144    case 16: //Default if BI_BITFIELDS not set is RGB 555
    145145        bitfields[0] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
    146146        bitfields[1] = (info->bmiHeader.biCompression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x03e0;
     
    436436    switch(info->bmiHeader.biBitCount) {
    437437    case 15:
    438     case 16:
     438    case 16: //Default if BI_BITFIELDS not set is RGB 555
    439439        bitfields[0] = (info->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
    440440        bitfields[1] = (info->bmiHeader.biCompression == BI_BITFIELDS) ?  *((DWORD *)info->bmiColors + 1) : 0x03e0;
  • trunk/src/gdi32/dibitmap.cpp

    r5931 r5967  
    1 /* $Id: dibitmap.cpp,v 1.21 2001-06-08 11:03:32 sandervl Exp $ */
     1/* $Id: dibitmap.cpp,v 1.22 2001-06-11 15:57:15 sandervl Exp $ */
    22
    33/*
     
    3131                                const BITMAPINFO *lpbmi, UINT fuUsage)
    3232{
    33   int iHeight;
    34   HBITMAP rc;
    35 
    36   //SvL: Completely wrong result when creating a 1bpp bitmap here (converted
    37   //     to 8bpp by Open32)
    38   if(lpbmih->biBitCount == 1) {
    39     dprintf(("WARNING: CreateDIBitmap doesn't handle 1bpp bitmaps very well!!!!!"));
    40   }
    41 
    42   //TEMPORARY HACK TO PREVENT CRASH IN OPEN32 (WSeB GA)
    43 
    44   iHeight = lpbmih->biHeight;
    45   if(lpbmih->biHeight < 0)
    46   {
    47     dprintf(("GDI32: CreateDIBitmap negative height! (%d,%d)", lpbmih->biWidth, lpbmih->biHeight));
    48     ((BITMAPINFOHEADER *)lpbmih)->biHeight = -lpbmih->biHeight;
    49   }
    50 
    51   // 2000/09/01 PH Netscape 4.7
    52   // If color depth of lpbhmi is 16 bit and lpbmi is 8 bit,
    53   // Open32 will crash since it won't allocate any palette color memory,
    54   // however wants to copy it later on ...
    55   int biBitCount = lpbmih->biBitCount;
    56 
    57   if (lpbmih->biBitCount != lpbmi->bmiHeader.biBitCount)
    58   {
    59     dprintf(("GDI32: CreateDIBitmap: color depths of bitmaps differ! (%d,%d\n",
    60              lpbmih->biBitCount,
    61              lpbmi->bmiHeader.biBitCount));
    62 
    63     ((BITMAPINFOHEADER *)lpbmih)->biBitCount = lpbmi->bmiHeader.biBitCount;
    64   }
    65 
    66   rc = O32_CreateDIBitmap(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
    67 
    68   dprintf(("GDI32: CreateDIBitmap %x %x %x %x %x returned %x (%d,%d, bps %d)", hdc, lpbmih, fdwInit, lpbInit, fuUsage, rc, lpbmih->biWidth, lpbmih->biHeight, lpbmih->biBitCount));
    69 
    70   ((BITMAPINFOHEADER *)lpbmih)->biHeight   = iHeight;
    71   ((BITMAPINFOHEADER *)lpbmih)->biBitCount = biBitCount;
    72 
    73   return rc;
     33    int iHeight;
     34    HBITMAP rc;
     35    DWORD bitfields[3];
     36    WORD *newbits = NULL;
     37
     38    //SvL: Completely wrong result when creating a 1bpp bitmap here (converted
     39    //     to 8bpp by Open32)
     40    if(lpbmih->biBitCount == 1) {
     41        dprintf(("WARNING: CreateDIBitmap doesn't handle 1bpp bitmaps very well!!!!!"));
     42    }
     43
     44    //TEMPORARY HACK TO PREVENT CRASH IN OPEN32 (WSeB GA)
     45
     46    iHeight = lpbmih->biHeight;
     47    if(lpbmih->biHeight < 0)
     48    {
     49        dprintf(("GDI32: CreateDIBitmap negative height! (%d,%d)", lpbmih->biWidth, lpbmih->biHeight));
     50        ((BITMAPINFOHEADER *)lpbmih)->biHeight = -lpbmih->biHeight;
     51    }
     52
     53    // 2000/09/01 PH Netscape 4.7
     54    // If color depth of lpbhmi is 16 bit and lpbmi is 8 bit,
     55    // Open32 will crash since it won't allocate any palette color memory,
     56    // however wants to copy it later on ...
     57    int biBitCount = lpbmih->biBitCount;
     58
     59    if (lpbmih->biBitCount != lpbmi->bmiHeader.biBitCount)
     60    {
     61        dprintf(("GDI32: CreateDIBitmap: color depths of bitmaps differ! (%d,%d\n", lpbmih->biBitCount,
     62                lpbmi->bmiHeader.biBitCount));
     63
     64        ((BITMAPINFOHEADER *)lpbmih)->biBitCount = lpbmi->bmiHeader.biBitCount;
     65    }
     66
     67    switch(lpbmih->biBitCount) {
     68    case 15:
     69    case 16: //Default if BI_BITFIELDS not set is RGB 555
     70        bitfields[0] = (lpbmih->biCompression == BI_BITFIELDS) ? *(DWORD *)lpbmi->bmiColors : 0x7c00;
     71        bitfields[1] = (lpbmih->biCompression == BI_BITFIELDS) ?  *((DWORD *)lpbmi->bmiColors + 1) : 0x03e0;
     72        bitfields[2] = (lpbmih->biCompression == BI_BITFIELDS) ?  *((DWORD *)lpbmi->bmiColors + 2) : 0x001f;
     73        break;
     74    case 32:
     75        bitfields[0] = (lpbmih->biCompression == BI_BITFIELDS) ? *(DWORD *)lpbmi->bmiColors : 0xff0000;
     76        bitfields[1] = (lpbmih->biCompression == BI_BITFIELDS) ?  *((DWORD *)lpbmi->bmiColors + 1) : 0xff00;
     77        bitfields[2] = (lpbmih->biCompression == BI_BITFIELDS) ?  *((DWORD *)lpbmi->bmiColors + 2) : 0xff;
     78        break;
     79    default:
     80        bitfields[0] = 0;
     81        bitfields[1] = 0;
     82        bitfields[2] = 0;
     83        break;
     84    }
     85    if(bitfields[1] == 0x3E0 && lpbInit && fdwInit == CBM_INIT)
     86    {//RGB 555?
     87        dprintf(("RGB 555->565 conversion required %x %x %x", bitfields[0], bitfields[1], bitfields[2]));
     88
     89        int imgsize = CalcBitmapSize(lpbmih->biBitCount, lpbmih->biWidth, lpbmih->biHeight);
     90
     91        newbits = (WORD *)malloc(imgsize);
     92        if(CPUFeatures & CPUID_MMX) {
     93             RGB555to565MMX(newbits, (WORD *)lpbInit, imgsize/sizeof(WORD));
     94        }
     95        else RGB555to565(newbits, (WORD *)lpbInit, imgsize/sizeof(WORD));
     96        lpbInit = newbits;
     97    }
     98
     99    rc = O32_CreateDIBitmap(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
     100
     101    dprintf(("GDI32: CreateDIBitmap %x %x %x %x %x returned %x (%d,%d, bps %d)", hdc, lpbmih, fdwInit, lpbInit, fuUsage, rc, lpbmih->biWidth, lpbmih->biHeight, lpbmih->biBitCount));
     102
     103    if(newbits) free(newbits);
     104
     105    ((BITMAPINFOHEADER *)lpbmih)->biHeight   = iHeight;
     106    ((BITMAPINFOHEADER *)lpbmih)->biBitCount = biBitCount;
     107
     108    return rc;
    74109}
    75110//******************************************************************************
     
    77112HBITMAP WIN32API CreateCompatibleBitmap( HDC hdc, int nWidth, int nHeight)
    78113{
    79  HBITMAP hBitmap;
     114    HBITMAP hBitmap;
    80115
    81116    hBitmap = O32_CreateCompatibleBitmap(hdc, nWidth, nHeight);
     
    94129//******************************************************************************
    95130HBITMAP WIN32API CreateBitmap(int nWidth, int nHeight, UINT cPlanes,
    96                                  UINT cBitsPerPel, const void *lpvBits)
     131                              UINT cBitsPerPel, const void *lpvBits)
    97132{
    98133 HBITMAP hBitmap;
     
    121156  dprintf(("GDI32: CreateDIBSection %x %x %x %x %x %d", hdc, pbmi, iUsage, ppvBits, hSection, dwOffset));
    122157
    123   //SvL: 13-9-98: StarCraft uses bitmap with negative height
    124   iWidth = pbmi->bmiHeader.biWidth;
    125   if(pbmi->bmiHeader.biWidth < 0)
    126   {
    127     dprintf(("CreateDIBSection: width %d", pbmi->bmiHeader.biWidth));
     158    //SvL: 13-9-98: StarCraft uses bitmap with negative height
     159    iWidth = pbmi->bmiHeader.biWidth;
     160    if(pbmi->bmiHeader.biWidth < 0)
     161    {
     162        dprintf(("CreateDIBSection: width %d", pbmi->bmiHeader.biWidth));
    128163        pbmi->bmiHeader.biWidth = -pbmi->bmiHeader.biWidth;
    129164        fFlip = FLIP_HOR;
    130   }
    131   iHeight = pbmi->bmiHeader.biHeight;
    132   if(pbmi->bmiHeader.biHeight < 0)
    133   {
    134     dprintf(("CreateDIBSection: height %d", pbmi->bmiHeader.biHeight));
     165    }
     166    iHeight = pbmi->bmiHeader.biHeight;
     167    if(pbmi->bmiHeader.biHeight < 0)
     168    {
     169        dprintf(("CreateDIBSection: height %d", pbmi->bmiHeader.biHeight));
    135170        pbmi->bmiHeader.biHeight = -pbmi->bmiHeader.biHeight;
    136171        fFlip |= FLIP_VERT;
    137172  }
    138173
    139   //SvL: RP7 (update) calls this api with hdc == 0
    140   if(hdc == 0) {
    141     hdc = GetWindowDC(GetDesktopWindow());
    142     fCreateDC = TRUE;
    143   }
    144   res = O32_CreateDIBitmap(hdc, &pbmi->bmiHeader, 0, NULL, pbmi, iUsage);
    145   if (res)
    146   {
    147     char PalSize;
    148     DIBSection *dsect;
    149 
    150     dsect = new DIBSection((BITMAPINFOHEADER_W *)&pbmi->bmiHeader, (char *)&pbmi->bmiColors, iUsage, hSection, dwOffset, (DWORD)res, fFlip);
    151 
    152     if(dsect != NULL)
    153     {
    154       PalSize = dsect->GetBitCount();
    155       if(PalSize <= 8)
    156       {
    157        ULONG Pal[256], nrcolors;
    158        LOGPALETTE tmpPal = { 0x300,1,{0,0,0,0}};
    159        HPALETTE hpalCur, hpalTmp;
    160 
    161         // Now get the current Palette from the DC
    162         hpalTmp = CreatePalette(&tmpPal);
    163         hpalCur = SelectPalette(hdc, hpalTmp, FALSE);
    164 
    165         // and use it to set the DIBColorTable
    166         nrcolors = GetPaletteEntries( hpalCur, 0, 1<<PalSize, (LPPALETTEENTRY)&Pal);
    167         dsect->SetDIBColorTable(0, nrcolors, (LPPALETTEENTRY)&Pal);
    168 
    169         // Restore the DC Palette
    170         SelectPalette(hdc,hpalCur,FALSE);
    171         DeleteObject(hpalTmp);
    172       }
    173 //SvL: Shouldn't an app explicitely select the dib section into the hdc?
    174 //     (RealPlayer does this)
    175 #if 0
    176       // Set the hdc in the DIBSection so we can update the palete if a new
    177       // Palette etc. gets selected into the DC.
    178 
    179       dsect->SelectDIBObject(hdc);
     174    //SvL: RP7 (update) calls this api with hdc == 0
     175    if(hdc == 0) {
     176        hdc = CreateCompatibleDC(0);
     177        fCreateDC = TRUE;
     178    }
     179    res = O32_CreateDIBitmap(hdc, &pbmi->bmiHeader, 0, NULL, pbmi, iUsage);
     180    if (res)
     181    {
     182        char PalSize;
     183        DIBSection *dsect;
     184
     185        dsect = new DIBSection((BITMAPINFOHEADER_W *)&pbmi->bmiHeader, (char *)&pbmi->bmiColors, iUsage, hSection, dwOffset, (DWORD)res, fFlip);
     186
     187        if(dsect != NULL)
     188        {
     189            PalSize = dsect->GetBitCount();
     190            if(PalSize <= 8)
     191            {
     192                ULONG Pal[256], nrcolors;
     193                LOGPALETTE tmpPal = { 0x300,1,{0,0,0,0}};
     194                HPALETTE hpalCur, hpalTmp;
     195
     196                // Now get the current Palette from the DC
     197                hpalTmp = CreatePalette(&tmpPal);
     198                hpalCur = SelectPalette(hdc, hpalTmp, FALSE);
     199
     200                // and use it to set the DIBColorTable
     201                nrcolors = GetPaletteEntries( hpalCur, 0, 1<<PalSize, (LPPALETTEENTRY)&Pal);
     202                dsect->SetDIBColorTable(0, nrcolors, (LPPALETTEENTRY)&Pal);
     203
     204                // Restore the DC Palette
     205                SelectPalette(hdc,hpalCur,FALSE);
     206                DeleteObject(hpalTmp);
     207            }
     208
     209            if(ppvBits!=NULL)
     210                *ppvBits = dsect->GetDIBObject();
     211
     212            pbmi->bmiHeader.biWidth = iWidth;
     213            pbmi->bmiHeader.biHeight = iHeight;
     214
     215            if(fCreateDC) ReleaseDC(GetDesktopWindow(), hdc);
     216            return(res);
     217        }
     218    }
     219    if(fCreateDC) DeleteDC(hdc);
     220
     221    /* Error.  */
     222    if (res)
     223        DeleteObject(res);
     224    *ppvBits = NULL;
     225
     226#ifdef DEBUG
     227    dprintf(("GDI32: CreateDIBSection, error!\n"));
     228    dprintf(("pbmi->biWidth    %d", pbmi->bmiHeader.biWidth));
     229    dprintf(("pbmi->biHeight   %d", pbmi->bmiHeader.biHeight));
     230    dprintf(("pbmi->biBitCount %d", pbmi->bmiHeader.biBitCount));
    180231#endif
    181232
    182       if(ppvBits!=NULL)
    183         *ppvBits = dsect->GetDIBObject();
    184 
    185       pbmi->bmiHeader.biWidth = iWidth;
    186       pbmi->bmiHeader.biHeight = iHeight;
    187 
    188       if(fCreateDC) ReleaseDC(GetDesktopWindow(), hdc);
    189       return(res);
    190     }
    191   }
    192   if(fCreateDC) ReleaseDC(GetDesktopWindow(), hdc);
    193 
    194   /* Error.  */
    195   if (res)
    196     DeleteObject(res);
    197   *ppvBits = NULL;
    198 #ifdef DEBUG
    199   dprintf(("GDI32: CreateDIBSection, error!\n"));
    200   dprintf(("pbmi->biWidth    %d", pbmi->bmiHeader.biWidth));
    201   dprintf(("pbmi->biHeight   %d", pbmi->bmiHeader.biHeight));
    202   dprintf(("pbmi->biBitCount %d", pbmi->bmiHeader.biBitCount));
    203 #endif
    204 
    205   return 0;
     233    return 0;
    206234}
    207235//******************************************************************************
     
    210238                               RGBQUAD *pColors)
    211239{
    212  DIBSection *dsect = DIBSection::findHDC(hdc);
    213  UINT rc;
    214  int i;
    215 
    216   dprintf(("GetDIBColorTable %x %d->%d %x", hdc, uStartIndex, cEntries, pColors));
    217 
    218   if(dsect)
    219   {
     240    DIBSection *dsect = DIBSection::findHDC(hdc);
     241    UINT rc;
     242    int i;
     243
     244    dprintf(("GetDIBColorTable %x %d->%d %x", hdc, uStartIndex, cEntries, pColors));
     245
     246    if(dsect)
     247    {
    220248       return(dsect->GetDIBColorTable(uStartIndex, cEntries, pColors));
    221   }
    222   //TODO: Is this correct?????
    223   //      Wine returns 0 if bitmap selected into dc with bpp > 8
    224   HPALETTE hpal = GetCurrentObject(hdc, OBJ_PAL);
    225   rc = O32_GetPaletteEntries(hpal, uStartIndex,
    226                              cEntries, (PALETTEENTRY *)pColors);
    227   for(i=0;
    228       i<cEntries;
    229       i++)
    230   {
    231     BYTE tmp;
    232     tmp = pColors[i].rgbBlue;
    233     pColors[i].rgbBlue = pColors[i].rgbRed;
    234     pColors[i].rgbRed = tmp;
    235     pColors[i].rgbReserved = 0;
    236   }
    237   dprintf(("GDI32: GetDIBColorTable returns %d\n", rc));
    238   return(rc);
     249    }
     250    //TODO: Is this correct?????
     251    //      Wine returns 0 if bitmap selected into dc with bpp > 8
     252    HPALETTE hpal = GetCurrentObject(hdc, OBJ_PAL);
     253    rc = O32_GetPaletteEntries(hpal, uStartIndex, cEntries, (PALETTEENTRY *)pColors);
     254    for(i=0;i<cEntries;i++)
     255    {
     256        BYTE tmp;
     257        tmp = pColors[i].rgbBlue;
     258        pColors[i].rgbBlue = pColors[i].rgbRed;
     259        pColors[i].rgbRed = tmp;
     260        pColors[i].rgbReserved = 0;
     261    }
     262    dprintf(("GDI32: GetDIBColorTable returns %d\n", rc));
     263    return(rc);
    239264}
    240265//******************************************************************************
     
    243268                               RGBQUAD *pColors)
    244269{
    245  DIBSection *dsect = DIBSection::findHDC(hdc);
    246 
    247   dprintf(("GDI32: SetDIBColorTable %x %d,%d %x", hdc, uStartIndex, cEntries, pColors));
    248   if(dsect)
    249   {
    250     return(dsect->SetDIBColorTable(uStartIndex, cEntries, pColors));
    251   }
    252   else
    253     return(0);
     270    DIBSection *dsect = DIBSection::findHDC(hdc);
     271
     272    dprintf(("GDI32: SetDIBColorTable %x %d,%d %x", hdc, uStartIndex, cEntries, pColors));
     273    if(dsect)
     274    {
     275        return(dsect->SetDIBColorTable(uStartIndex, cEntries, pColors));
     276    }
     277    else return(0);
    254278}
    255279//******************************************************************************
     
    300324    // set proper color masks
    301325    switch(lpbi->bmiHeader.biBitCount) {
     326    case 15:
    302327    case 16: //RGB 565
    303        ((DWORD*)(lpbi->bmiColors))[0] = 0xF800;
     328       ((DWORD*)(lpbi->bmiColors))[0] = 0x7c00;
    304329       ((DWORD*)(lpbi->bmiColors))[1] = 0x03E0;
    305330       ((DWORD*)(lpbi->bmiColors))[2] = 0x001F;
     
    312337       break;
    313338    }
    314     if(nrlines && lpvBits && lpbi->bmiHeader.biBitCount == 16 && ((DWORD*)(lpbi->bmiColors))[1] == 0x3E0) 
     339    if(nrlines && lpvBits && lpbi->bmiHeader.biBitCount == 16 && ((DWORD*)(lpbi->bmiColors))[1] == 0x3E0)
    315340    {//RGB 555?
    316341        dprintf(("RGB 565->555 conversion required"));
     
    339364{
    340365    int ret;
     366    DWORD bitfields[3];
     367    WORD *newbits = NULL;
    341368
    342369    dprintf(("GDI32: SetDIBits %x %x %x %x %x %x %x", hdc, hBitmap, startscan, numlines, pBits, pBitmapInfo, usage));
     
    351378        int   ret;
    352379
    353         dprintf(("Flipping 1bpp bitmap and calling SetBitmapBits (WORKAROUND) (%d -> %d)", dibwidth, bmpwidth));
     380        dprintf(("Flipping 1bpp bitmap and calling SetBitmapBits (WORKAROUND) (%d -> %d)", dibwidth, bmpwidth));
    354381        newpix += ((pBitmapInfo->bmiHeader.biHeight-1)*bmpwidth);
    355382
     
    374401    }
    375402#endif
     403
     404    switch(pBitmapInfo->bmiHeader.biBitCount) {
     405    case 15:
     406    case 16: //Default if BI_BITFIELDS not set is RGB 555
     407        bitfields[0] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)pBitmapInfo->bmiColors : 0x7c00;
     408        bitfields[1] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ?  *((DWORD *)pBitmapInfo->bmiColors + 1) : 0x03e0;
     409        bitfields[2] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ?  *((DWORD *)pBitmapInfo->bmiColors + 2) : 0x001f;
     410        break;
     411    case 32:
     412        bitfields[0] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)pBitmapInfo->bmiColors : 0xff0000;
     413        bitfields[1] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ?  *((DWORD *)pBitmapInfo->bmiColors + 1) : 0xff00;
     414        bitfields[2] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ?  *((DWORD *)pBitmapInfo->bmiColors + 2) : 0xff;
     415        break;
     416    default:
     417        bitfields[0] = 0;
     418        bitfields[1] = 0;
     419        bitfields[2] = 0;
     420        break;
     421    }
     422    if(pBits && bitfields[1] == 0x3E0)
     423    {//RGB 555?
     424        dprintf(("RGB 555->565 conversion required %x %x %x", bitfields[0], bitfields[1], bitfields[2]));
     425
     426        int imgsize = CalcBitmapSize(pBitmapInfo->bmiHeader.biBitCount,
     427                                     pBitmapInfo->bmiHeader.biWidth, numlines);
     428
     429        newbits = (WORD *)malloc(imgsize);
     430        if(CPUFeatures & CPUID_MMX) {
     431             RGB555to565MMX(newbits, (WORD *)pBits, imgsize/sizeof(WORD));
     432        }
     433        else RGB555to565(newbits, (WORD *)pBits, imgsize/sizeof(WORD));
     434        pBits = newbits;
     435    }
     436
    376437    ret = O32_SetDIBits(hdc, hBitmap, startscan, numlines, pBits, pBitmapInfo, usage);
     438    if(newbits) free(newbits);
     439
    377440    if(DIBSection::getSection() != NULL)
    378441    {
Note: See TracChangeset for help on using the changeset viewer.