* Rewrote header.

* Cleaned up sources.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32752 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-08-27 13:40:07 +00:00
parent 2089178aac
commit 8780d2073d
2 changed files with 170 additions and 390 deletions
+35 -94
View File
@@ -1,113 +1,54 @@
/*****************************************************************************/ /*
// File: BitmapStream.h * Copyright 2009, Haiku Inc. All Rights Reserved.
// Class: BBitmapStream * Distributed under the terms of the MIT License.
// Reimplemented by: Travis Smith, Michael Wilber, Translation Kit Team */
// Reimplementation: 2002-04 #ifndef _BITMAP_STREAM_H
//
// Description: BPositionIO based object to read/write bitmap format to/from
// a BBitmap object.
//
// The BTranslationUtils class uses this object and makes it
// easy for users to load bitmaps.
//
// Copyright (c) 2002 OpenBeOS Project
//
// Original Version: Copyright 1998, Be Incorporated, All Rights Reserved.
// Copyright 1995-1997, Jon Watte
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#if !defined(_BITMAP_STREAM_H)
#define _BITMAP_STREAM_H #define _BITMAP_STREAM_H
#include <BeBuild.h>
#include <TranslationDefs.h>
#include <DataIO.h>
#include <TranslatorFormats.h>
#include <ByteOrder.h> #include <ByteOrder.h>
#include <DataIO.h>
#include <TranslationDefs.h>
#include <TranslatorFormats.h>
class BBitmap; class BBitmap;
class BBitmapStream : public BPositionIO { class BBitmapStream : public BPositionIO {
public: public:
BBitmapStream(BBitmap *bitmap = NULL); BBitmapStream(BBitmap* bitmap = NULL);
// Initializes the stream to use map as the bitmap for stream virtual ~BBitmapStream();
// operations. If map is null, a BBitmap is created when properly
// formatted data is written to the stream.
~BBitmapStream();
// Destroys the BBitmap held by this object if it has not been
// detached and frees fpBigEndianHeader
// Overrides from BPositionIO virtual ssize_t ReadAt(off_t offset, void* buffer, size_t size);
ssize_t ReadAt(off_t pos, void *buffer, size_t size); virtual ssize_t WriteAt(off_t offset, const void* buffer,
// reads data from the bitmap into buffer size_t size);
ssize_t WriteAt(off_t pos, const void *data, size_t size); virtual off_t Seek(off_t position, uint32 seekMode);
// writes the data from data into this bitmap virtual off_t Position() const;
// (if the data is properly formatted) virtual off_t Size() const;
off_t Seek(off_t position, uint32 whence); virtual status_t SetSize(off_t size);
// sets the stream position member
off_t Position() const;
// returns the current stream position
off_t Size() const;
// returns the size of the data
status_t SetSize(off_t size);
// sets the amount of memory to be used by this object
status_t DetachBitmap(BBitmap **outMap); status_t DetachBitmap(BBitmap** _bitmap);
// "Detaches" the bitmap used by this stream and returns it
// to the user through outMap. This allows the user to
// use the bitmap even after the BBitmapStream that it
// came from has been deleted.
protected: protected:
TranslatorBitmap fHeader; void SwapHeader(const TranslatorBitmap* source,
// stores the bitmap header information in the TranslatorBitmap* destination);
// host format, used to determine the format of
// the bitmap data and to see if the data is valid protected:
BBitmap *fBitmap; TranslatorBitmap fHeader;
// the actual bitmap used by this object BBitmap* fBitmap;
size_t fPosition; size_t fPosition;
// current data position size_t fSize;
size_t fSize; bool fDetached;
// size of the data stored
bool fDetached;
// true if the bitmap has been detached, false if not
void SwapHeader(const TranslatorBitmap *source,
TranslatorBitmap *destination);
// swaps the byte order of source, no matter what the
// byte order of source is, and copies the result to
// destination
private: private:
TranslatorBitmap *fpBigEndianHeader;
// same data as in fHeader, but in Big Endian format
// (Intel machines are Little Endian)
// For maintaining binary compatibility with past and future
// versions of this object
long fUnused[5];
virtual void _ReservedBitmapStream1(); virtual void _ReservedBitmapStream1();
virtual void _ReservedBitmapStream2(); virtual void _ReservedBitmapStream2();
private:
TranslatorBitmap* fBigEndianHeader;
long _reserved[5];
}; };
#endif /* _BITMAP_STREAM_H */
#endif // _BITMAP_STREAM_H
+135 -296
View File
@@ -1,69 +1,38 @@
/*****************************************************************************/ /*
// Copyright (c) 2002-2005 Haiku Project * Copyright 2002-2009, Haiku, Inc.
// * Distributed under the terms of the MIT License.
// Reimplemented by: Travis Smith, Michael Wilber, Translation Kit Team *
// * Authors:
// Description: BPositionIO based object to read/write bitmap format to/from * Travis Smith
// a BBitmap object. * Michael Wilber
// */
// The BTranslationUtils class uses this object and makes it
// easy for users to load bitmaps.
//
// Original Version: Copyright 1998, Be Incorporated, All Rights Reserved.
// Copyright 1995-1997, Jon Watte
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/*****************************************************************************/
#include <BitmapStream.h> #include <BitmapStream.h>
#include <Bitmap.h>
#include <Debug.h>
#include <string.h> #include <string.h>
#include <Bitmap.h>
#include <Debug.h>
// ---------------------------------------------------------------
// Constructor /*! Initializes this object to either use the BBitmap passed to
// it as the object to read/write to or to create a BBitmap
// Initializes this object to either use the BBitmap passed to when data is written to this object.
// it as the object to read/write to or to create a BBitmap
// when data is written to this object. \param bitmap the bitmap used to read from/write to, if it is NULL, a
// bitmap is created when this object is written to.
// Preconditions: */
// BBitmapStream::BBitmapStream(BBitmap* bitmap)
// Parameters: bitmap, the bitmap used to read from/write to,
// if it is NULL, a bitmap is created when
// this object is written to
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
BBitmapStream::BBitmapStream(BBitmap *bitmap)
{ {
fBitmap = bitmap; fBitmap = bitmap;
fDetached = false; fDetached = false;
fPosition = 0; fPosition = 0;
fSize = 0; fSize = 0;
fpBigEndianHeader = new TranslatorBitmap; fBigEndianHeader = new TranslatorBitmap;
// Extract header information if bitmap is available // Extract header information if bitmap is available
if (fBitmap) { if (fBitmap != NULL) {
fHeader.magic = B_TRANSLATOR_BITMAP; fHeader.magic = B_TRANSLATOR_BITMAP;
fHeader.bounds = fBitmap->Bounds(); fHeader.bounds = fBitmap->Bounds();
fHeader.rowBytes = fBitmap->BytesPerRow(); fHeader.rowBytes = fBitmap->BytesPerRow();
@@ -71,70 +40,42 @@ BBitmapStream::BBitmapStream(BBitmap *bitmap)
fHeader.dataSize = static_cast<uint32> fHeader.dataSize = static_cast<uint32>
((fHeader.bounds.Height() + 1) * fHeader.rowBytes); ((fHeader.bounds.Height() + 1) * fHeader.rowBytes);
fSize = sizeof(TranslatorBitmap) + fHeader.dataSize; fSize = sizeof(TranslatorBitmap) + fHeader.dataSize;
if (B_HOST_IS_BENDIAN) if (B_HOST_IS_BENDIAN)
memcpy(fpBigEndianHeader, &fHeader, sizeof(TranslatorBitmap)); memcpy(fBigEndianHeader, &fHeader, sizeof(TranslatorBitmap));
else else
SwapHeader(&fHeader, fpBigEndianHeader); SwapHeader(&fHeader, fBigEndianHeader);
} }
} }
// ---------------------------------------------------------------
// Destructor
//
// Destroys memory used by this object, but does not destroy the
// bitmap used by this object if it has been detached. This is so
// the user can use that bitmap after this object is destroyed.
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
BBitmapStream::~BBitmapStream() BBitmapStream::~BBitmapStream()
{ {
if (!fDetached) if (!fDetached)
delete fBitmap; delete fBitmap;
fBitmap = NULL;
delete fBigEndianHeader;
delete fpBigEndianHeader;
fpBigEndianHeader = NULL;
} }
// ---------------------------------------------------------------
// ReadAt /*! Reads data from the stream at a specific position and for a
// specific amount. The first sizeof(TranslatorBitmap) bytes
// Reads data from the stream at a specific position and for a are the bitmap header. The header is always written out
// specific amount. The first sizeof(TranslatorBitmap) bytes and read in as Big Endian byte order.
// are the bitmap header. The header is always written out
// and read in as Big Endian byte order. \param pos, the position in the stream to read from buffer, where the data
// will be read into size, the amount of data to read
// Preconditions: \return B_ERROR if there is no bitmap stored by the stream, B_BAD_VALUE if
// buffer is NULL or pos is invalid or the amount read if the result >= 0
// Parameters: pos, the position in the stream to read from */
// buffer, where the data will be read into
// size, the amount of data to read
//
// Postconditions:
//
// Returns: B_ERROR if there is no bitmap stored by the stream
// or if pos is a bad value,
// B_BAD_VALUE if buffer is NULL or pos is invalid
// or the amount read if the result >= 0
// ---------------------------------------------------------------
ssize_t ssize_t
BBitmapStream::ReadAt(off_t pos, void *buffer, size_t size) BBitmapStream::ReadAt(off_t pos, void* buffer, size_t size)
{ {
if (!fBitmap) if (!fBitmap)
return B_ERROR; return B_ERROR;
if (!size) if (size == 0)
return B_NO_ERROR; return B_OK;
if (pos >= fSize) if (pos >= fSize || pos < 0 || buffer == NULL)
return B_ERROR;
if (!buffer || pos < 0)
return B_BAD_VALUE; return B_BAD_VALUE;
ssize_t toRead; ssize_t toRead;
@@ -142,7 +83,7 @@ BBitmapStream::ReadAt(off_t pos, void *buffer, size_t size)
if (pos < sizeof(TranslatorBitmap)) { if (pos < sizeof(TranslatorBitmap)) {
toRead = sizeof(TranslatorBitmap) - pos; toRead = sizeof(TranslatorBitmap) - pos;
source = (reinterpret_cast<uint8 *>(fpBigEndianHeader)) + pos; source = (reinterpret_cast<uint8 *>(fBigEndianHeader)) + pos;
} else { } else {
toRead = fSize - pos; toRead = fSize - pos;
source = (reinterpret_cast<uint8 *>(fBitmap->Bits())) + pos - source = (reinterpret_cast<uint8 *>(fBitmap->Bits())) + pos -
@@ -155,31 +96,22 @@ BBitmapStream::ReadAt(off_t pos, void *buffer, size_t size)
return toRead; return toRead;
} }
// ---------------------------------------------------------------
// WriteAt /*! Writes data to the bitmap from data, starting at position pos
// of size, size. The first sizeof(TranslatorBitmap) bytes
// Writes data to the bitmap from data, starting at position pos of data must be the TranslatorBitmap header in the Big
// of size, size. The first sizeof(TranslatorBitmap) bytes Endian byte order, otherwise, the data will fail to be
// of data must be the TranslatorBitmap header in the Big successfully written.
// Endian byte order, otherwise, the data will fail to be
// successfully written. \param pos, the position in the stream to write to data, the data to write
// to the stream size, the size of the data to write to the stream
// Preconditions: \return B_BAD_VALUE if size is bad or data is NULL or pos is invalid,
// B_MISMATCHED_VALUES if the bitmap header is bad,
// Parameters: pos, the position in the stream to write to B_ERROR if error allocating memory or setting up big endian header,
// data, the data to write to the stream or the amount written if the result is >= 0
// size, the size of the data to write to the stream */
//
// Postconditions:
//
// Returns: B_BAD_VALUE if size is bad or data is NULL or pos is invalid,
// B_MISMATCHED_VALUES if the bitmap header is bad,
// B_ERROR if error allocating memory or setting up
// big endian header,
// or the amount written if the result is >= 0
// ---------------------------------------------------------------
ssize_t ssize_t
BBitmapStream::WriteAt(off_t pos, const void *data, size_t size) BBitmapStream::WriteAt(off_t pos, const void* data, size_t size)
{ {
if (!size) if (!size)
return B_NO_ERROR; return B_NO_ERROR;
@@ -216,10 +148,10 @@ BBitmapStream::WriteAt(off_t pos, const void *data, size_t size)
// If we change the header, the rest needs to be reset // If we change the header, the rest needs to be reset
if (pos == sizeof(TranslatorBitmap)) { if (pos == sizeof(TranslatorBitmap)) {
// Setup both host and Big Endian byte order bitmap headers // Setup both host and Big Endian byte order bitmap headers
memcpy(fpBigEndianHeader, &fHeader, sizeof(TranslatorBitmap)); memcpy(fBigEndianHeader, &fHeader, sizeof(TranslatorBitmap));
if (B_HOST_IS_LENDIAN) if (B_HOST_IS_LENDIAN)
SwapHeader(fpBigEndianHeader, &fHeader); SwapHeader(fBigEndianHeader, &fHeader);
if (fBitmap if (fBitmap
&& (fBitmap->Bounds() != fHeader.bounds && (fBitmap->Bounds() != fHeader.bounds
|| fBitmap->ColorSpace() != fHeader.colors || fBitmap->ColorSpace() != fHeader.colors
@@ -236,7 +168,8 @@ BBitmapStream::WriteAt(off_t pos, const void *data, size_t size)
if (!fBitmap) if (!fBitmap)
return B_ERROR; return B_ERROR;
if ((uint32)fBitmap->BytesPerRow() != fHeader.rowBytes) { if ((uint32)fBitmap->BytesPerRow() != fHeader.rowBytes) {
fprintf(stderr, "BitmapStream %ld %ld\n", fBitmap->BytesPerRow(), fHeader.rowBytes); fprintf(stderr, "BitmapStream %ld %ld\n",
fBitmap->BytesPerRow(), fHeader.rowBytes);
return B_MISMATCHED_VALUES; return B_MISMATCHED_VALUES;
} }
} }
@@ -247,59 +180,37 @@ BBitmapStream::WriteAt(off_t pos, const void *data, size_t size)
return written; return written;
} }
// ---------------------------------------------------------------
// Seek /*! Changes the current stream position.
//
// Changes the current stream position. \param position the position offset
// \param seekMode decides how the position offset is used:
// Preconditions: SEEK_CUR, position is added to current stream position
// SEEK_END, position is added to the end stream position
// Parameters: position, the position offset SEEK_SET, the stream position is set to position
// whence, decides how the position offset is used \return B_BAD_VALUE if the position is bad or the new position value if the
// SEEK_CUR, position is added to current result >= 0
// stream position */
// SEEK_END, position is added to the end
// stream position
// SEEK_SET, the stream position is set to
// position
//
// Postconditions:
//
// Returns: B_BAD_VALUE if the position is bad
// or the new position value if the result >= 0
// ---------------------------------------------------------------
off_t off_t
BBitmapStream::Seek(off_t position, uint32 whence) BBitmapStream::Seek(off_t position, uint32 seekMode)
{ {
// When whence == SEEK_SET, it just falls through to // When whence == SEEK_SET, it just falls through to
// fPosition = position // fPosition = position
if (whence == SEEK_CUR) if (seekMode == SEEK_CUR)
position += fPosition; position += fPosition;
if (whence == SEEK_END) else if (seekMode == SEEK_END)
position += fSize; position += fSize;
if (position < 0) if (position < 0 || position > fSize)
return B_BAD_VALUE; return B_BAD_VALUE;
if (position > fSize)
return B_BAD_VALUE;
fPosition = position; fPosition = position;
return fPosition; return fPosition;
} }
// ---------------------------------------------------------------
// Position /*! Returns the current stream position
// */
// Returns the current stream position
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns: returns the curren stream position
// ---------------------------------------------------------------
off_t off_t
BBitmapStream::Position() const BBitmapStream::Position() const
{ {
@@ -307,40 +218,23 @@ BBitmapStream::Position() const
} }
// ---------------------------------------------------------------
// Size /*! Returns the curren stream size
// */
// Returns the curren stream size
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns: returns the current stream size
// ---------------------------------------------------------------
off_t off_t
BBitmapStream::Size() const BBitmapStream::Size() const
{ {
return fSize; return fSize;
} }
// ---------------------------------------------------------------
// SetSize /*! Sets the size of the data, but I'm not sure if this function has any real
// purpose.
// Sets the size of the data, but I'm not sure if this function
// has any real purpose. \param size the size to set the stream size to.
// \return B_BAD_VALUE, if size is a bad value, B_NO_ERROR, if size is a
// Preconditions: valid value
// */
// Parameters: size, the size to set the stream size to.
//
// Postconditions:
//
// Returns: B_BAD_VALUE, if size is a bad value
// B_NO_ERROR, if size is a valid value
// ---------------------------------------------------------------
status_t status_t
BBitmapStream::SetSize(off_t size) BBitmapStream::SetSize(off_t size)
{ {
@@ -348,117 +242,62 @@ BBitmapStream::SetSize(off_t size)
return B_BAD_VALUE; return B_BAD_VALUE;
if (fBitmap && (size > fHeader.dataSize + sizeof(TranslatorBitmap))) if (fBitmap && (size > fHeader.dataSize + sizeof(TranslatorBitmap)))
return B_BAD_VALUE; return B_BAD_VALUE;
// Problem: // Problem:
// What if someone calls SetSize() before writing the header, // What if someone calls SetSize() before writing the header,
// so we don't know what bitmap to create? // so we don't know what bitmap to create?
// Solution: // Solution:
// We assume people will write the header before any data, // We assume people will write the header before any data,
// so SetSize() is really not going to do anything. // so SetSize() is really not going to do anything.
if (fBitmap) if (fBitmap != NULL)
// if we checked that the size was OK
fSize = size; fSize = size;
return B_NO_ERROR; return B_NO_ERROR;
} }
// ---------------------------------------------------------------
// DetachBitmap /*! Returns the internal bitmap through outBitmap so the user
// can do whatever they want to it. It means that when the
// Returns the internal bitmap through outBitmap so the user BBitmapStream is deleted, the bitmap is not deleted. After
// can do whatever they want to it. It means that when the the bitmap has been detached, it is still used by the stream,
// BBitmapStream is deleted, the bitmap is not deleted. After but it is never deleted by the stream.
// the bitmap has been detached, it is still used by the stream,
// but it is never deleted by the stream. \param _bitmap where the bitmap is detached to
// \return B_BAD_VALUE, if outBitmap is NULL, B_ERROR, if the bitmap is NULL or
// Preconditions: has already been detached, B_OK, if the bitmap was successfully detached
// */
// Parameters: outBitmap, where the bitmap is detached to
//
// Postconditions:
//
// Returns: B_BAD_VALUE, if outBitmap is NULL
// B_ERROR, if the bitmap is NULL or
// has already been detached
// B_NO_ERROR, if the bitmap was successfully detached
// ---------------------------------------------------------------
status_t status_t
BBitmapStream::DetachBitmap(BBitmap **outBitmap) BBitmapStream::DetachBitmap(BBitmap** _bitmap)
{ {
if (!outBitmap) if (_bitmap == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
if (!fBitmap || fDetached) { if (!fBitmap || fDetached)
*outBitmap = NULL;
return B_ERROR; return B_ERROR;
}
fDetached = true; fDetached = true;
*outBitmap = fBitmap; *_bitmap = fBitmap;
return B_NO_ERROR; return B_OK;
} }
// ---------------------------------------------------------------
// SwapHeader /*! Swaps the byte order of source, no matter what the
// byte order, and copies the result to destination
// Swaps the byte order of source, no matter what the
// byte order, and copies the result to destination \param source data to be swapped
// \param destination where the swapped data will be copied to
// Preconditions: both parameters must not be null */
//
// Parameters: source, data to be swapped
//
// destination, where the swapped data will
// be copied to
//
// Postconditions:
//
// Returns:
//
// ---------------------------------------------------------------
void void
BBitmapStream::SwapHeader(const TranslatorBitmap *source, BBitmapStream::SwapHeader(const TranslatorBitmap* source,
TranslatorBitmap *destination) TranslatorBitmap* destination)
{ {
if (source == NULL || destination == NULL)
return;
memcpy(destination, source, sizeof(TranslatorBitmap)); memcpy(destination, source, sizeof(TranslatorBitmap));
swap_data(B_UINT32_TYPE, destination, sizeof(TranslatorBitmap), swap_data(B_UINT32_TYPE, destination, sizeof(TranslatorBitmap),
B_SWAP_ALWAYS); B_SWAP_ALWAYS);
} }
// ---------------------------------------------------------------
// _ReservedBitmapStream1()
//
// It doesn't do anything :). Its here only for past/future
// binary compatibility.
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
void
BBitmapStream::_ReservedBitmapStream1()
{
}
// ---------------------------------------------------------------
// _ReservedBitmapStream2()
//
// It doesn't do anything :). Its only here for past/future
// binary compatibility.
//
// Preconditions:
//
// Parameters:
//
// Postconditions:
//
// Returns:
// ---------------------------------------------------------------
void
BBitmapStream::_ReservedBitmapStream2()
{
}
void BBitmapStream::_ReservedBitmapStream1() {}
void BBitmapStream::_ReservedBitmapStream2() {}