Changeset 3070 for libpipi/trunk


Ignore:
Timestamp:
Oct 23, 2008, 1:56:48 AM (12 years ago)
Author:
Sam Hocevar
Message:

Full GDI+ load and save support.

Location:
libpipi/trunk/pipi
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • libpipi/trunk/pipi/codec.c

    r3067 r3070  
    5151        ret = pipi_load_sdl(name);
    5252#endif
     53#if USE_GDIPLUS
     54    if(!ret)
     55        ret = pipi_load_gdiplus(name);
     56#endif
    5357#if USE_GDI
    5458    if(!ret)
     
    9599        ret = pipi_save_sdl(img, name);
    96100#endif
     101#if USE_GDIPLUS
     102    if(ret < 0)
     103        ret = pipi_save_gdiplus(img, name);
     104#endif
    97105#if USE_GDI
    98106    if(ret < 0)
    99107        ret = pipi_save_gdi(img, name);
    100 #endif
    101 #if USE_GDIPLUS
    102     if(ret < 0)
    103         ret = pipi_save_gdiplus(img, name);
    104108#endif
    105109#if USE_COCOA
  • libpipi/trunk/pipi/codec/gdiplus.cpp

    r3067 r3070  
    2424
    2525#include <windows.h>
     26#include <gdiplus.h>
    2627
    2728#include "pipi.h"
     
    3031extern "C" pipi_image_t *pipi_load_gdiplus(const char *name)
    3132{
    32     BITMAPINFO binfo;
    33     pipi_image_t *img;
    34     pipi_pixels_t *p;
    35     uint8_t *data;
    36     HBITMAP hbmap;
    37     HDC hdc;
    38 
    39     hbmap = (HBITMAP)LoadImage(NULL, name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    40     if(!hbmap)
     33    size_t len;
     34    if(mbstowcs_s(&len, NULL, 0, name, _TRUNCATE) != 0)
    4135        return NULL;
    42 
    43     hdc = CreateCompatibleDC(NULL);
    44     SelectObject(hdc, hbmap);
    45 
    46     memset(&binfo, 0, sizeof(binfo));
    47     binfo.bmiHeader.biSize = sizeof(binfo.bmiHeader);
    48     if(!GetDIBits(hdc, hbmap, 0, 0, 0, &binfo, DIB_RGB_COLORS))
     36    wchar_t *wname = new wchar_t[len];
     37    if(mbstowcs_s(NULL, wname, len, name, _TRUNCATE) != 0)
    4938    {
    50         ReleaseDC(0, hdc);
    51         DeleteObject(hbmap);
     39        delete[] wname;
    5240        return NULL;
    5341    }
    5442
    55     img = pipi_new(binfo.bmiHeader.biWidth, binfo.bmiHeader.biHeight);
    56     p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
    57     data = (uint8_t *)p->pixels;
     43    ULONG_PTR token;
     44    Gdiplus::GdiplusStartupInput input;
     45    Gdiplus::GdiplusStartup(&token, &input, NULL);
    5846
    59     binfo.bmiHeader.biBitCount = 32;
    60     binfo.bmiHeader.biCompression = BI_RGB;
    61     binfo.bmiHeader.biHeight = - abs(binfo.bmiHeader.biHeight);
    62     if(!GetDIBits(hdc, hbmap, 0, abs(binfo.bmiHeader.biHeight), data,
    63                   &binfo, DIB_RGB_COLORS))
     47    Gdiplus::Bitmap *b = Gdiplus::Bitmap::FromFile(wname, 0);
     48    if(!b)
    6449    {
    65         ReleaseDC(0, hdc);
    66         DeleteObject(hbmap);
     50        delete[] wname;
     51        return NULL;
     52    }
     53    delete[] wname;
     54
     55    Gdiplus::BitmapData bdata;
     56    Gdiplus::Rect rect(0, 0, b->GetWidth(), b->GetHeight());
     57
     58    if(b->LockBits(&rect, Gdiplus::ImageLockModeRead,
     59                   PixelFormat32bppARGB, &bdata) != Gdiplus::Ok)
     60    {
     61        delete b;
    6762        return NULL;
    6863    }
    6964
    70     /* FIXME: do we need to swap bytes? Apparently Vista doesn't need it,
    71      * but we'd need a more thorough test. */
     65    pipi_image_t *img = pipi_new(b->GetWidth(), b->GetHeight());
     66    pipi_pixels_t *p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
     67    memcpy(p->pixels, bdata.Scan0, bdata.Width * bdata.Height * 4);
     68
     69    b->UnlockBits(&bdata);
     70    delete b;
    7271
    7372    img->codec_priv = NULL;
     
    7675    img->u8 = 1;
    7776
    78     ReleaseDC(0, hdc);
    79     DeleteObject(hbmap);
    80 
    8177    return img;
    8278}
     
    8480extern "C" int pipi_save_gdiplus(pipi_image_t *img, const char *name)
    8581{
    86     BITMAPINFOHEADER binfo;
    87     BITMAPFILEHEADER bfheader;
    88     uint8_t dummy[4] = { 0 };
    89     HANDLE hfile;
    90     pipi_pixels_t *p;
    91     DWORD ret = 0;
    92     uint8_t *data;
    93     int x, y, padding;
     82    wchar_t const *fmt;
     83    if(strstr(name, ".gif"))
     84        fmt = L"image/gif";
     85    else if(strstr(name, ".jpeg") || strstr(name, ".jpeg"))
     86        fmt = L"image/jpeg";
     87    else if(strstr(name, ".png"))
     88        fmt = L"image/png";
     89    else if(strstr(name, ".tiff"))
     90        fmt = L"image/tiff";
    9491
    95     p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
    96     data = (uint8_t *)p->pixels;
     92    unsigned int num = 0, size = 0;
     93    Gdiplus::GetImageEncodersSize(&num, &size);
     94    if(size == 0)
     95        return -1;
     96    Gdiplus::ImageCodecInfo *codecs
     97        = (Gdiplus::ImageCodecInfo *)(malloc(size));
     98    if(!codecs)
     99        return -1;
     100    Gdiplus::GetImageEncoders(num, size, codecs);
     101    CLSID clsid;
     102    for(unsigned int i = 0; i < num; i++)
     103    {
     104        if(wcscmp(codecs[i].MimeType, fmt) == 0)
     105        {
     106            clsid = codecs[i].Clsid;
     107            break;
     108        }
     109    }
    97110
    98     padding = ((img->w * 3) + 3) / 4 * 4 - img->w * 3;
     111    size_t len;
     112    if(mbstowcs_s(&len, NULL, 0, name, _TRUNCATE) != 0)
     113        return NULL;
     114    wchar_t *wname = new wchar_t[len];
     115    if(mbstowcs_s(NULL, wname, len, name, _TRUNCATE) != 0)
     116    {
     117        delete[] wname;
     118        return -1;
     119    }
    99120
    100     memset(&binfo, 0, sizeof(binfo));
    101     binfo.biSize = sizeof(binfo);
    102     binfo.biWidth = img->w;
    103     binfo.biHeight = img->h;
    104     binfo.biPlanes = 1;
    105     binfo.biBitCount = 24;
    106     binfo.biCompression = BI_RGB;
    107     binfo.biSizeImage = (img->w * 3 + padding) * img->h;
     121    ULONG_PTR token;
     122    Gdiplus::GdiplusStartupInput input;
     123    Gdiplus::GdiplusStartup(&token, &input, NULL);
    108124
    109     memset(&bfheader, 0, sizeof(bfheader));
    110     bfheader.bfType = 0x4D42;
    111     bfheader.bfOffBits = sizeof(bfheader) + sizeof(binfo);
    112     bfheader.bfSize = bfheader.bfOffBits + binfo.biSizeImage;
     125    Gdiplus::Bitmap *b = new Gdiplus::Bitmap(img->w, img->h,
     126                                             PixelFormat32bppARGB);
    113127
    114     /* We don’t even create the bitmap object, since we know exactly
    115      * what kind of file we are saving. But later, when we support
    116      * different depths and BMP options, we'll need to care about it. */
    117     hfile = CreateFile(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
    118                        FILE_ATTRIBUTE_ARCHIVE, NULL);
    119     if(!hfile)
     128    Gdiplus::BitmapData bdata;
     129    Gdiplus::Rect rect(0, 0, img->w, img->h);
     130
     131    if(b->LockBits(&rect, Gdiplus::ImageLockModeWrite,
     132                   PixelFormat32bppARGB, &bdata) != Gdiplus::Ok)
     133    {
     134        delete b;
    120135        return -1;
    121     WriteFile(hfile, &bfheader, sizeof(bfheader), &ret, NULL);
    122     WriteFile(hfile, &binfo, sizeof(binfo), &ret, NULL);
    123     for(y = 0; y < img->h; y++)
     136    }
     137
     138    pipi_pixels_t *p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
     139    memcpy(bdata.Scan0, p->pixels, bdata.Width * bdata.Height * 4);
     140
     141    b->UnlockBits(&bdata);
     142
     143    if(b->Save(wname, &clsid, NULL) != Gdiplus::Ok)
    124144    {
    125         for(x = 0; x < img->w; x++)
    126         {
    127             uint8_t tmp[3];
    128             tmp[0] = data[4 * (img->w * (img->h - 1 - y) + x) + 0];
    129             tmp[1] = data[4 * (img->w * (img->h - 1 - y) + x) + 1];
    130             tmp[2] = data[4 * (img->w * (img->h - 1 - y) + x) + 2];
    131             WriteFile(hfile, tmp, 3, &ret, NULL);
    132         }
    133         if(padding)
    134             WriteFile(hfile, dummy, padding, &ret, NULL);
     145        delete[] wname;
     146        delete b;
     147        return -1;
    135148    }
    136     CloseHandle(hfile);
     149    delete[] wname;
     150    delete b;
    137151
    138152    return 0;
  • libpipi/trunk/pipi/libpipi.vcproj

    r3067 r3070  
    22<VisualStudioProject
    33        ProjectType="Visual C++"
    4         Version="8.00"
     4        Version="8,00"
    55        Name="libpipi"
    66        ProjectGUID="{48A34C3A-1E36-49B7-92C4-E982FDCB90C0}"
     
    6161                        <Tool
    6262                                Name="VCLinkerTool"
     63                                AdditionalDependencies="gdiplus.lib"
    6364                                OutputFile="$(OutDir)\$(ProjectName)-0.dll"
    6465                                LinkIncremental="2"
     
    134135                        <Tool
    135136                                Name="VCLinkerTool"
     137                                AdditionalDependencies="gdiplus.lib"
    136138                                OutputFile="$(OutDir)\$(ProjectName)-0.dll"
    137139                                LinkIncremental="2"
     
    217219                        </File>
    218220                        <File
    219                                 RelativePath=".\filter\autocontrast.c"
    220                                 >
    221                         </File>
    222                         <File
    223                                 RelativePath=".\paint\bezier.c"
    224                                 >
    225                         </File>
    226                         <File
    227                                 RelativePath=".\filter\blur.c"
    228                                 >
    229                         </File>
    230                         <File
    231221                                RelativePath=".\codec.c"
    232222                                >
    233223                        </File>
    234224                        <File
    235                                 RelativePath=".\filter\color.c"
    236                                 >
    237                         </File>
    238                         <File
    239225                                RelativePath=".\colorstring.c"
    240226                                >
     
    245231                        </File>
    246232                        <File
    247                                 RelativePath=".\filter\convolution.c"
    248                                 >
    249                         </File>
    250                         <File
    251                                 RelativePath=".\dither\dbs.c"
    252                                 >
    253                         </File>
    254                         <File
    255                                 RelativePath=".\filter\dilate.c"
    256                                 >
    257                         </File>
    258                         <File
    259233                                RelativePath=".\dither.c"
    260234                                >
    261235                        </File>
    262236                        <File
    263                                 RelativePath=".\dither\ediff.c"
    264                                 >
    265                         </File>
    266                         <File
    267                                 RelativePath=".\paint\floodfill.c"
    268                                 >
    269                         </File>
    270                         <File
    271                                 RelativePath=".\codec\gdi.c"
    272                                 >
    273                         </File>
    274                         <File
    275                                 RelativePath=".\codec\gdiplus.cpp"
    276                                 >
    277                         </File>
    278                         <File
    279                                 RelativePath=".\histogram\histogram.c"
    280                                 >
    281                         </File>
    282                         <File
    283                                 RelativePath=".\paint\line.c"
    284                                 >
    285                         </File>
    286                         <File
    287                                 RelativePath=".\combine\mean.c"
    288                                 >
    289                         </File>
    290                         <File
    291237                                RelativePath=".\measure.c"
    292238                                >
    293239                        </File>
    294240                        <File
    295                                 RelativePath=".\filter\median.c"
    296                                 >
    297                         </File>
    298                         <File
    299                                 RelativePath=".\combine\minmax.c"
    300                                 >
    301                         </File>
    302                         <File
    303                                 RelativePath=".\combine\mulscreen.c"
    304                                 >
    305                         </File>
    306                         <File
    307                                 RelativePath=".\render\noise.c"
    308                                 >
    309                         </File>
    310                         <File
    311                                 RelativePath=".\dither\ordered.c"
    312                                 >
    313                         </File>
    314                         <File
    315                                 RelativePath=".\codec\oric.c"
    316                                 >
    317                         </File>
    318                         <File
    319                                 RelativePath=".\dither\ostromoukhov.c"
    320                                 >
    321                         </File>
    322                         <File
    323241                                RelativePath=".\pipi.c"
    324242                                >
     
    329247                        </File>
    330248                        <File
    331                                 RelativePath=".\dither\random.c"
    332                                 >
    333                         </File>
    334                         <File
    335249                                RelativePath=".\quantize\reduce.c"
    336250                                >
     
    341255                        </File>
    342256                        <File
    343                                 RelativePath=".\combine\rgb.c"
    344                                 >
    345                         </File>
    346                         <File
    347                                 RelativePath=".\render\screen.c"
    348                                 >
    349                         </File>
    350                         <File
    351257                                RelativePath=".\stock.c"
    352258                                >
    353259                        </File>
    354                         <File
    355                                 RelativePath=".\combine\subadd.c"
    356                                 >
    357                         </File>
    358                         <File
    359                                 RelativePath=".\paint\tile.c"
    360                                 >
    361                         </File>
    362                         <File
    363                                 RelativePath=".\filter\transform.c"
    364                                 >
    365                         </File>
     260                        <Filter
     261                                Name="codec"
     262                                >
     263                                <File
     264                                        RelativePath=".\codec\gdi.c"
     265                                        >
     266                                </File>
     267                                <File
     268                                        RelativePath=".\codec\gdiplus.cpp"
     269                                        >
     270                                </File>
     271                                <File
     272                                        RelativePath=".\codec\oric.c"
     273                                        >
     274                                </File>
     275                        </Filter>
     276                        <Filter
     277                                Name="combine"
     278                                >
     279                                <File
     280                                        RelativePath=".\combine\mean.c"
     281                                        >
     282                                </File>
     283                                <File
     284                                        RelativePath=".\combine\minmax.c"
     285                                        >
     286                                </File>
     287                                <File
     288                                        RelativePath=".\combine\mulscreen.c"
     289                                        >
     290                                </File>
     291                                <File
     292                                        RelativePath=".\combine\rgb.c"
     293                                        >
     294                                </File>
     295                                <File
     296                                        RelativePath=".\combine\subadd.c"
     297                                        >
     298                                </File>
     299                        </Filter>
     300                        <Filter
     301                                Name="dither"
     302                                >
     303                                <File
     304                                        RelativePath=".\dither\dbs.c"
     305                                        >
     306                                </File>
     307                                <File
     308                                        RelativePath=".\dither\ediff.c"
     309                                        >
     310                                </File>
     311                                <File
     312                                        RelativePath=".\dither\ordered.c"
     313                                        >
     314                                </File>
     315                                <File
     316                                        RelativePath=".\dither\ostromoukhov.c"
     317                                        >
     318                                </File>
     319                                <File
     320                                        RelativePath=".\dither\random.c"
     321                                        >
     322                                </File>
     323                        </Filter>
     324                        <Filter
     325                                Name="filter"
     326                                >
     327                                <File
     328                                        RelativePath=".\filter\autocontrast.c"
     329                                        >
     330                                </File>
     331                                <File
     332                                        RelativePath=".\filter\blur.c"
     333                                        >
     334                                </File>
     335                                <File
     336                                        RelativePath=".\filter\color.c"
     337                                        >
     338                                </File>
     339                                <File
     340                                        RelativePath=".\filter\convolution.c"
     341                                        >
     342                                </File>
     343                                <File
     344                                        RelativePath=".\filter\dilate.c"
     345                                        >
     346                                </File>
     347                                <File
     348                                        RelativePath=".\filter\median.c"
     349                                        >
     350                                </File>
     351                                <File
     352                                        RelativePath=".\filter\transform.c"
     353                                        >
     354                                </File>
     355                        </Filter>
     356                        <Filter
     357                                Name="histogram"
     358                                >
     359                                <File
     360                                        RelativePath=".\histogram\histogram.c"
     361                                        >
     362                                </File>
     363                        </Filter>
     364                        <Filter
     365                                Name="paint"
     366                                >
     367                                <File
     368                                        RelativePath=".\paint\bezier.c"
     369                                        >
     370                                </File>
     371                                <File
     372                                        RelativePath=".\paint\floodfill.c"
     373                                        >
     374                                </File>
     375                                <File
     376                                        RelativePath=".\paint\line.c"
     377                                        >
     378                                </File>
     379                                <File
     380                                        RelativePath=".\paint\tile.c"
     381                                        >
     382                                </File>
     383                        </Filter>
     384                        <Filter
     385                                Name="render"
     386                                >
     387                                <File
     388                                        RelativePath=".\render\noise.c"
     389                                        >
     390                                </File>
     391                                <File
     392                                        RelativePath=".\render\screen.c"
     393                                        >
     394                                </File>
     395                        </Filter>
    366396                </Filter>
    367397        </Files>
Note: See TracChangeset for help on using the changeset viewer.