Sayfayı Yazdır | Pencereyi Kapat

leptonica write bmp with pixWriteMemBmp function

Nereden Yazdırıldığı: Datakent
Kategori: Diğer bölümler
Forum Adı: C, C++, Visual C++
Forum Tanımlaması: C, C++, Visual C++ Örnekleri
URL: http://forum.datakent.com/forum_posts.asp?TID=2472
Tarih: 28.Mart.2024 Saat 13:15


Konu: leptonica write bmp with pixWriteMemBmp function
Mesajı Yazan: aziz.alkurt
Konu: leptonica write bmp with pixWriteMemBmp function
Mesaj Tarihi: 16.Aralik.2012 Saat 17:26
leptonica - bmpio.c
//----------------------------------------------------------------------------------------------------------------------
l_int32
pixWriteMemBmp(l_uint8  **pdata,
               size_t    *psize,
               PIX       *pix)
{
l_uint32    offbytes, filebytes, fileimagebytes;
l_int32     width, height, depth, d, xres, yres;
l_uint16    bfType, bfSize, bfFill1, bfReserved1, bfReserved2;
l_uint16    bfOffBits, bfFill2, biPlanes, biBitCount;
l_uint16    sval;
l_uint32    biSize, biWidth, biHeight, biCompression, biSizeImage;
l_uint32    biXPelsPerMeter, biYPelsPerMeter, biClrUsed, biClrImportant;
l_int32     pixWpl, pixBpl, extrabytes, writeerror;
l_int32     fileBpl, fileWpl;
l_int32     i, j, k;
l_int32     heapcm;  /* extra copy of cta on the heap ? 1 : 0 */
l_uint8    *data;
l_uint8     pel[4];
l_uint32   *line, *pword;
PIXCMAP    *cmap;
l_uint8    *cta;          /* address of the bmp color table array */
l_int32     cmaplen;      /* number of bytes in the bmp colormap */
l_int32     ncolors, val, stepsize;
RGBA_QUAD  *pquad;
l_uint8 *pdataTMP;
unsigned int hacked;
    PROCNAME("pixWriteMemBmp");

    if (!pix)
        return ERROR_INT("pix not defined", procName, 1);

    width  = pixGetWidth(pix);
    height = pixGetHeight(pix);
    d  = pixGetDepth(pix);
    if (d == 2)
        L_WARNING("writing 2 bpp bmp file; nobody else can read", procName);
    depth = d;
    if (d == 32)
        depth = 24;
    xres = (l_int32)(39.37 * (l_float32)pixGetXRes(pix) + 0.5);  /* to ppm */
    yres = (l_int32)(39.37 * (l_float32)pixGetYRes(pix) + 0.5);  /* to ppm */

    pixWpl = pixGetWpl(pix);
    pixBpl = 4 * pixWpl;
    fileWpl = (width * depth + 31) / 32;
    fileBpl = 4 * fileWpl;
    fileimagebytes = height * fileBpl;

    heapcm = 0;
    if (d == 32) {   /* 24 bpp rgb; no colormap */
        ncolors = 0;
        cmaplen = 0;
    }
    else if ((cmap = pixGetColormap(pix))) {   /* existing colormap */
        ncolors = pixcmapGetCount(cmap);
        cmaplen = ncolors * sizeof(RGBA_QUAD);
        cta = (l_uint8 *)cmap->array;
    }
    else {   /* no existing colormap; make a binary or gray one */
        if (d == 1) {
            cmaplen  = sizeof(bwmap);
            ncolors = 2;
            cta = (l_uint8 *)bwmap;
        }
        else {   /* d != 32; output grayscale version */
            ncolors = 1 << depth;
            cmaplen = ncolors * sizeof(RGBA_QUAD);

            heapcm = 1;
            if ((cta = (l_uint8 *)CALLOC(cmaplen, 1)) == NULL)
                return ERROR_INT("colormap alloc fail", procName, 1);

            stepsize = 255 / (ncolors - 1);
            for (i = 0, val = 0, pquad = (RGBA_QUAD *)cta;
                 i < ncolors;
                 i++, val += stepsize, pquad++) {
                pquad->blue = pquad->green = pquad->red = val;
            }
        }
    }

        /* Convert to little-endian and write the file header data */
    bfType = convertOnBigEnd16(BMP_ID);
    offbytes = BMP_FHBYTES + BMP_IHBYTES + cmaplen;
    filebytes = offbytes + fileimagebytes;
    *psize=filebytes;
    pdataTMP=(unsigned char*) malloc (sizeof(unsigned char)*filebytes);
    sval = filebytes & 0x0000ffff;
    bfSize = convertOnBigEnd16(sval);
    sval = (filebytes >> 16) & 0x0000ffff;
    bfFill1 = convertOnBigEnd16(sval);
    bfReserved1 = 0;
    bfReserved2 = 0;
    sval = offbytes & 0x0000ffff;
    bfOffBits = convertOnBigEnd16(sval);
    sval = (offbytes >> 16) & 0x0000ffff;
    bfFill2 = convertOnBigEnd16(sval);

    memcpy(pdataTMP,&bfType,2);
    memcpy(pdataTMP+2,&bfSize,2);
    memcpy(pdataTMP+4,&bfFill1,2);
    memcpy(pdataTMP+6,&bfReserved1,2);
    memcpy(pdataTMP+8,&bfReserved1,2);
    memcpy(pdataTMP+10,&bfOffBits,2);
    memcpy(pdataTMP+12,&bfFill2,2);



        /* Convert to little-endian and write the info header data */
    biSize = convertOnBigEnd32(BMP_IHBYTES);
    biWidth = convertOnBigEnd32(width);
    biHeight = convertOnBigEnd32(height);
    biPlanes = convertOnBigEnd16(1);
    biBitCount = convertOnBigEnd16(depth);
    biCompression   = 0;
    biSizeImage = convertOnBigEnd32(fileimagebytes);
    biXPelsPerMeter = convertOnBigEnd32(xres);
    biYPelsPerMeter = convertOnBigEnd32(yres);
    biClrUsed = convertOnBigEnd32(ncolors);
    biClrImportant = convertOnBigEnd32(ncolors);

    memcpy(pdataTMP+14,&biSize,4);
    memcpy(pdataTMP+18,&biWidth,4);
    memcpy(pdataTMP+22,&biHeight,4);
    memcpy(pdataTMP+26,&biPlanes,2);
    memcpy(pdataTMP+28,&biBitCount,2);
    memcpy(pdataTMP+30,&biCompression,4);
    memcpy(pdataTMP+34,&biSizeImage,4);
    memcpy(pdataTMP+38,&biXPelsPerMeter,4);
    memcpy(pdataTMP+42,&biYPelsPerMeter,4);
    memcpy(pdataTMP+46,&biClrUsed,4);
    memcpy(pdataTMP+50,&biClrImportant,4);

    hacked=54;
        /* Write the colormap data */

    if (ncolors > 0)
    {
        memcpy(pdataTMP+hacked,cta,cmaplen);
        if (heapcm)
            FREE(cta);
        hacked+=cmaplen;
    }

        /* When you write a binary image with a colormap
         * that sets BLACK to 0, you must invert the data */
    if (depth == 1 && cmap && ((l_uint8 *)(cmap->array))[0] == 0x0) {
        pixInvert(pix, pix);
    }

    pixEndianByteSwap(pix);
    writeerror = 0;
    if (depth != 24)
    {   /* typ 1 or 8 bpp */

        data = (l_uint8 *)pixGetData(pix) + pixBpl * (height - 1);
        for (i = 0; i < height; i++)
        {
            memcpy(pdataTMP+hacked,data,fileBpl);
            hacked+=fileBpl;
            data -= pixBpl;
        }
    }
    else {  /* 32 bpp pix; 24 bpp file
             * See the comments in pixReadStreamBMP() to
             * understand the logic behind the pixel ordering below.
             * Note that we have again done an endian swap on
             * little endian machines before arriving here, so that
             * the bytes are ordered on both platforms as:
                        Red         Green        Blue         --
                    |-----------|------------|-----------|-----------|
             */
        extrabytes = fileBpl - 3 * width;
        line = pixGetData(pix) + pixWpl * (height - 1);
        for (i = 0; i < height; i++) {
            for (j = 0; j < width; j++) {
                pword = line + j;
                pel[2] = *((l_uint8 *)pword + COLOR_RED);
                pel[1] = *((l_uint8 *)pword + COLOR_GREEN);
                pel[0] = *((l_uint8 *)pword + COLOR_BLUE);
                memcpy(pdataTMP+hacked,&pel,3);
                hacked+=3;
            }
            if (extrabytes) {
                memcpy(pdataTMP+hacked,&pel,3);
                hacked+=extrabytes;
            }
            line -= pixWpl;
        }
    }

        /* Restore to original state */
    pixEndianByteSwap(pix);
    if (depth == 1 && cmap && ((l_uint8 *)(cmap->array))[0] == 0x0)
        pixInvert(pix, pix);

    if (writeerror)
        return ERROR_INT("image write fail", procName, 1);
    *pdata = (l_uint8*)pdataTMP;
    return 0;
}
//----------------------------------------------------------------------------------------------------------------------



Sayfayı Yazdır | Pencereyi Kapat