[haiku-commits] r41104 - haiku/trunk/src/add-ons/translators/bmp

  • From: korli@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 25 Mar 2011 23:28:30 +0100 (CET)

Author: korli
Date: 2011-03-25 23:28:30 +0100 (Fri, 25 Mar 2011)
New Revision: 41104
Changeset: https://dev.haiku-os.org/changeset/41104
Ticket: https://dev.haiku-os.org/ticket/7342

Modified:
   haiku/trunk/src/add-ons/translators/bmp/BMPTranslator.cpp
   haiku/trunk/src/add-ons/translators/bmp/BMPTranslator.h
Log:
support for top to bottom BMP files see #7342


Modified: haiku/trunk/src/add-ons/translators/bmp/BMPTranslator.cpp
===================================================================
--- haiku/trunk/src/add-ons/translators/bmp/BMPTranslator.cpp   2011-03-25 
22:13:48 UTC (rev 41103)
+++ haiku/trunk/src/add-ons/translators/bmp/BMPTranslator.cpp   2011-03-25 
22:28:30 UTC (rev 41104)
@@ -390,10 +390,8 @@
                }
                if (pmsheader) {
                        pmsheader->size = msheader.size;
-                       pmsheader->width = msheader.width;
-                       pmsheader->height = abs((int32)msheader.height);
-                               // TODO: negative height means the BMP is up 
side down
-                               // -> support this...
+                       pmsheader->width = abs(msheader.width);
+                       pmsheader->height = msheader.height;
                        pmsheader->planes = msheader.planes;
                        pmsheader->bitsperpixel = msheader.bitsperpixel;
                        pmsheader->compression = msheader.compression;
@@ -472,7 +470,7 @@
 
                                        pfileheader->dataOffset = 54;
                                        pmsheader->imagesize = 
get_rowbytes(pmsheader->width,
-                                               pmsheader->bitsperpixel) * 
pmsheader->height;
+                                               pmsheader->bitsperpixel) * 
abs(pmsheader->height);
                                        pfileheader->fileSize = 
pfileheader->dataOffset +
                                                pmsheader->imagesize;
 
@@ -492,7 +490,7 @@
 
                                        pfileheader->dataOffset = 54 + (ncolors 
* 4);
                                        pmsheader->imagesize = 
get_rowbytes(pmsheader->width,
-                                               pmsheader->bitsperpixel) * 
pmsheader->height;
+                                               pmsheader->bitsperpixel) * 
abs(pmsheader->height);
                                        pfileheader->fileSize = 
pfileheader->dataOffset +
                                                pmsheader->imagesize;
 
@@ -627,9 +625,9 @@
        int32 padding = get_padding(msheader.width, msheader.bitsperpixel);
        int32 bmpRowBytes =
                get_rowbytes(msheader.width, msheader.bitsperpixel);
-       uint32 bmppixrow = 0;
-       off_t bitsoffset = ((msheader.height - 1) * bitsRowBytes);
-       inSource->Seek(bitsoffset, SEEK_CUR);
+       int32 bmppixrow = 0;
+       if (msheader.height > 0)
+               inSource->Seek((msheader.height - 1) * bitsRowBytes, SEEK_CUR);
        uint8 *bmpRowData = new (nothrow) uint8[bmpRowBytes];
        if (!bmpRowData)
                return B_NO_MEMORY;
@@ -650,8 +648,9 @@
                }
        }
        while (rd == static_cast<ssize_t>(bitsRowBytes)) {
-
-               for (uint32 i = 0; i < msheader.width; i++) {
+               printf("translate_from_bits_to_bmp24() bmppixrow %ld\n", 
bmppixrow);
+       
+               for (int32 i = 0; i < msheader.width; i++) {
                        uint8 *bitspixel, *bmppixel;
                        uint16 val;
                        switch (fromspace) {
@@ -769,10 +768,11 @@
                // if I've read all of the pixel data, break
                // out of the loop so I don't try to read
                // non-pixel data
-               if (bmppixrow == msheader.height)
+               if (bmppixrow == abs(msheader.height))
                        break;
 
-               inSource->Seek(bitsRowBytes * -2, SEEK_CUR);
+               if (msheader.height > 0)
+                       inSource->Seek(bitsRowBytes * -2, SEEK_CUR);
                rd = inSource->Read(bitsRowData, bitsRowBytes);
        } // while (rd == bitsRowBytes)
 
@@ -813,9 +813,9 @@
        int32 padding = get_padding(msheader.width, msheader.bitsperpixel);
        int32 bmpRowBytes =
                get_rowbytes(msheader.width, msheader.bitsperpixel);
-       uint32 bmppixrow = 0;
-       off_t bitsoffset = ((msheader.height - 1) * bitsRowBytes);
-       inSource->Seek(bitsoffset, SEEK_CUR);
+       int32 bmppixrow = 0;
+       if (msheader.height > 0)
+               inSource->Seek((msheader.height - 1) * bitsRowBytes, SEEK_CUR);
        uint8 *bmpRowData = new (nothrow) uint8[bmpRowBytes];
        if (!bmpRowData)
                return B_NO_MEMORY;
@@ -833,10 +833,11 @@
                // if I've read all of the pixel data, break
                // out of the loop so I don't try to read
                // non-pixel data
-               if (bmppixrow == msheader.height)
+               if (bmppixrow == abs(msheader.height))
                        break;
 
-               inSource->Seek(bitsRowBytes * -2, SEEK_CUR);
+               if (msheader.height > 0)
+                       inSource->Seek(bitsRowBytes * -2, SEEK_CUR);
                rd = inSource->Read(bitsRowData, bitsRowBytes);
        } // while (rd == bitsRowBytes)
 
@@ -877,9 +878,9 @@
        uint8 pixelsPerByte = 8 / msheader.bitsperpixel;
        int32 bmpRowBytes =
                get_rowbytes(msheader.width, msheader.bitsperpixel);
-       uint32 bmppixrow = 0;
-       off_t bitsoffset = ((msheader.height - 1) * bitsRowBytes);
-       inSource->Seek(bitsoffset, SEEK_CUR);
+       int32 bmppixrow = 0;
+       if (msheader.height > 0)
+               inSource->Seek((msheader.height - 1) * bitsRowBytes, SEEK_CUR);
        uint8 *bmpRowData = new (nothrow) uint8[bmpRowBytes];
        if (!bmpRowData)
                return B_NO_MEMORY;
@@ -890,7 +891,7 @@
        }
        ssize_t rd = inSource->Read(bitsRowData, bitsRowBytes);
        while (rd == bitsRowBytes) {
-               uint32 bmppixcol = 0;
+               int32 bmppixcol = 0;
                memset(bmpRowData, 0, bmpRowBytes);
                for (int32 i = 0; (bmppixcol < msheader.width) &&
                        (i < bitsRowBytes); i++) {
@@ -918,10 +919,11 @@
                // if I've read all of the pixel data, break
                // out of the loop so I don't try to read
                // non-pixel data
-               if (bmppixrow == msheader.height)
+               if (bmppixrow == abs(msheader.height))
                        break;
 
-               inSource->Seek(bitsRowBytes * -2, SEEK_CUR);
+               if (msheader.height > 0)
+                       inSource->Seek(bitsRowBytes * -2, SEEK_CUR);
                rd = inSource->Read(bitsRowData, bitsRowBytes);
        } // while (rd == bitsRowBytes)
 
@@ -1025,7 +1027,7 @@
                msheader.width =
                        static_cast<uint32> (bitsHeader.bounds.Width() + 1);
                msheader.height =
-                       static_cast<uint32> (bitsHeader.bounds.Height() + 1);
+                       static_cast<int32> (bitsHeader.bounds.Height() + 1);
                msheader.planes = 1;
                msheader.xpixperm = 2835; // 72 dpi horizontal
                msheader.ypixperm = 2835; // 72 dpi vertical
@@ -1218,16 +1220,17 @@
        // Setup outDestination so that it can be written to
        // from the end of the file to the beginning instead of
        // the other way around
-       off_t bitsFileSize = (bitsRowBytes * msheader.height) +
+       off_t bitsFileSize = (bitsRowBytes * abs(msheader.height)) +
                sizeof(TranslatorBitmap);
        if (outDestination->SetSize(bitsFileSize) != B_OK) {
                // This call should work for BFile and BMallocIO objects,
                // but may not work for other BPositionIO based types
-               ERROR("BMPTranslator::translate_from_bmpnpal_to_bits() - failed 
to SetSize()\n");
+               ERROR("BMPTranslator::translate_from_bmpnpal_to_bits() - "
+                       "failed to SetSize()\n");
                return B_ERROR;
        }
-       off_t bitsoffset = (msheader.height - 1) * bitsRowBytes;
-       outDestination->Seek(bitsoffset, SEEK_CUR);
+       if (msheader.height > 0)
+               outDestination->Seek((msheader.height - 1) * bitsRowBytes, 
SEEK_CUR);
 
        // allocate row buffers
        uint8 *bmpRowData = new (nothrow) uint8[bmpRowBytes];
@@ -1248,7 +1251,8 @@
 
        status_t ret = B_OK;
 
-       for (uint32 y = 0; y < msheader.height; y++) {
+       uint32 rowCount = abs(msheader.height);
+       for (uint32 y = 0; y < rowCount; y++) {
                ssize_t read = inSource->Read(bmpRowData, bmpRowBytes);
                if (read != bmpRowBytes) {
                        // break on read error
@@ -1264,7 +1268,7 @@
                } else {
                        uint8 *pBitsPixel = bitsRowData;
                        uint8 *pBmpPixel = bmpRowData;
-                       for (uint32 i = 0; i < msheader.width; i++) {
+                       for (int32 i = 0; i < msheader.width; i++) {
                                pBitsPixel[0] = pBmpPixel[0];
                                pBitsPixel[1] = pBmpPixel[1];
                                pBitsPixel[2] = pBmpPixel[2];
@@ -1274,7 +1278,8 @@
                }
                // write row and seek backward by two rows
                ssize_t written = outDestination->Write(bitsRowData, 
bitsRowBytes);
-               outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
+               if (msheader.height > 0)
+                       outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
 
                if (written != bitsRowBytes) {
                        // break on write error
@@ -1335,20 +1340,20 @@
 
        int32 bmpRowBytes =
                get_rowbytes(msheader.width, msheader.bitsperpixel);
-       uint32 bmppixrow = 0;
+       int32 bmppixrow = 0;
 
        // Setup outDestination so that it can be written to
        // from the end of the file to the beginning instead of
        // the other way around
        int32 bitsRowBytes = msheader.width * 4;
-       off_t bitsFileSize = (bitsRowBytes * msheader.height) +
+       off_t bitsFileSize = (bitsRowBytes * abs(msheader.height)) +
                sizeof(TranslatorBitmap);
        if (outDestination->SetSize(bitsFileSize) != B_OK)
                // This call should work for BFile and BMallocIO objects,
                // but may not work for other BPositionIO based types
                return B_ERROR;
-       off_t bitsoffset = ((msheader.height - 1) * bitsRowBytes);
-       outDestination->Seek(bitsoffset, SEEK_CUR);
+       if (msheader.height > 0)
+               outDestination->Seek((msheader.height - 1) * bitsRowBytes, 
SEEK_CUR);
 
        // allocate row buffers
        uint8 *bmpRowData = new (nothrow) uint8[bmpRowBytes];
@@ -1362,7 +1367,7 @@
        memset(bitsRowData, 0xff, bitsRowBytes);
        ssize_t rd = inSource->Read(bmpRowData, bmpRowBytes);
        while (rd == static_cast<ssize_t>(bmpRowBytes)) {
-               for (uint32 i = 0; i < msheader.width; i++) {
+               for (int32 i = 0; i < msheader.width; i++) {
                        uint8 indices = (bmpRowData + (i / pixelsPerByte))[0];
                        uint8 index;
                        index = (indices >>
@@ -1377,10 +1382,11 @@
                // if I've read all of the pixel data, break
                // out of the loop so I don't try to read
                // non-pixel data
-               if (bmppixrow == msheader.height)
+               if (bmppixrow == abs(msheader.height))
                        break;
 
-               outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
+               if (msheader.height > 0)
+                       outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
                rd = inSource->Read(bmpRowData, bmpRowBytes);
        }
 
@@ -1458,8 +1464,9 @@
        // Setup outDestination so that it can be written to
        // from the end of the file to the beginning instead of
        // the other way around
+       int32 rowCount = abs(msheader.height);
        int32 bitsRowBytes = msheader.width * 4;
-       off_t bitsFileSize = (bitsRowBytes * msheader.height) +
+       off_t bitsFileSize = (bitsRowBytes * rowCount) +
                sizeof(TranslatorBitmap);
        if (outDestination->SetSize(bitsFileSize) != B_OK)
                // This call should work for BFile and BMallocIO objects,
@@ -1469,12 +1476,12 @@
        if (!bitsRowData)
                return B_NO_MEMORY;
        memset(bitsRowData, 0xff, bitsRowBytes);
-       uint32 bmppixcol = 0, bmppixrow = 0;
+       int32 bmppixcol = 0, bmppixrow = 0;
        uint32 defaultcolor = *(uint32*)palette;
+       off_t rowOffset = msheader.height > 0 ? bitsRowBytes * -2 : 0;
        // set bits output to last row in the image
-       off_t bitsoffset = ((msheader.height - (bmppixrow + 1)) * bitsRowBytes) 
+
-               (bmppixcol * 4);
-       outDestination->Seek(bitsoffset, SEEK_CUR);
+       if (msheader.height > 0)
+               outDestination->Seek((msheader.height - 1) * bitsRowBytes, 
SEEK_CUR);
        ssize_t rd = inSource->Read(&count, 1);
        while (rd > 0) {
                // repeated color
@@ -1522,8 +1529,8 @@
                                        outDestination->Write(bitsRowData, 
bitsRowBytes);
                                        bmppixcol = 0;
                                        bmppixrow++;
-                                       if (bmppixrow < msheader.height)
-                                               
outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
+                                       if (bmppixrow < rowCount)
+                                               outDestination->Seek(rowOffset, 
SEEK_CUR);
                                        break;
 
                                // end of bitmap
@@ -1533,18 +1540,18 @@
                                                
outDestination->Write(bitsRowData, bitsRowBytes);
                                                bmppixcol = 0;
                                                bmppixrow++;
-                                               if (bmppixrow < msheader.height)
-                                                       
outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
+                                               if (bmppixrow < rowCount)
+                                                       
outDestination->Seek(rowOffset, SEEK_CUR);
                                        }
 
-                                       while (bmppixrow < msheader.height) {
+                                       while (bmppixrow < rowCount) {
                                                pixelcpy(bitsRowData + 
(bmppixcol * 4), defaultcolor,
                                                        msheader.width - 
bmppixcol);
                                                
outDestination->Write(bitsRowData, bitsRowBytes);
                                                bmppixcol = 0;
                                                bmppixrow++;
-                                               if (bmppixrow < msheader.height)
-                                                       
outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
+                                               if (bmppixrow < rowCount)
+                                                       
outDestination->Seek(rowOffset, SEEK_CUR);
                                        }
                                        rd = 0;
                                                // break out of while loop
@@ -1565,7 +1572,7 @@
 
                                        // abort if dx or dy is too large
                                        if ((dx + bmppixcol >= msheader.width) 
||
-                                               (dy + bmppixrow >= 
msheader.height)) {
+                                               (dy + bmppixrow >= rowCount)) {
                                                rd = -1;
                                                break;
                                        }
@@ -1581,10 +1588,10 @@
                                                bmppixcol = 0;
                                                bmppixrow++;
                                                dy--;
-                                               
outDestination->Seek(bitsRowBytes * -2, SEEK_CUR);
+                                               outDestination->Seek(rowOffset, 
SEEK_CUR);
                                        }
 
-                                       if (bmppixcol < 
static_cast<uint32>(lastcol + dx)) {
+                                       if (bmppixcol < 
static_cast<int32>(lastcol + dx)) {
                                                pixelcpy(bitsRowData + 
(bmppixcol * 4), defaultcolor,
                                                        dx + lastcol - 
bmppixcol);
                                                bmppixcol = dx + lastcol;
@@ -1747,7 +1754,7 @@
                bitsHeader.bounds.left = 0;
                bitsHeader.bounds.top = 0;
                bitsHeader.bounds.right = msheader.width - 1;
-               bitsHeader.bounds.bottom = msheader.height - 1;
+               bitsHeader.bounds.bottom = abs(msheader.height) - 1;
 
                // read in palette and/or skip non-BMP data
                uint8 bmppalette[1024];
@@ -1787,7 +1794,7 @@
 
                bitsHeader.rowBytes = msheader.width * 4;
                bitsHeader.colors = B_RGB32;
-               int32 datasize = bitsHeader.rowBytes * msheader.height;
+               int32 datasize = bitsHeader.rowBytes * abs(msheader.height);
                bitsHeader.dataSize = datasize;
 
                // write out Be's Bitmap header

Modified: haiku/trunk/src/add-ons/translators/bmp/BMPTranslator.h
===================================================================
--- haiku/trunk/src/add-ons/translators/bmp/BMPTranslator.h     2011-03-25 
22:13:48 UTC (rev 41103)
+++ haiku/trunk/src/add-ons/translators/bmp/BMPTranslator.h     2011-03-25 
22:28:30 UTC (rev 41104)
@@ -67,8 +67,8 @@
 
 struct MSInfoHeader {
        uint32 size;                    // size of this struct (40)
-       uint32 width;                   // bitmap width
-       uint32 height;                  // bitmap height
+       int32 width;                    // bitmap width
+       int32 height;                   // bitmap height
        uint16 planes;                  // number of planes, always 1?
        uint16 bitsperpixel;    // bits per pixel, (1,4,8,16, 24 or 32)
        uint32 compression;             // type of compression


Other related posts:

  • » [haiku-commits] r41104 - haiku/trunk/src/add-ons/translators/bmp - korli