Exemple #1
0
/**
 *  Read 16 bit values from a little endian binary file.
 *
 *  This function will read 16 bit values from a little endian binary file
 *  and convert them to the native byte order.
 *
 *  Error messages from this function are sent to the message handler
 *  (see msngr_init_log() and msngr_init_mail()).
 *
 *  @param  fd    - file descriptor
 *  @param  data  - pointer to the output data array
 *  @param  nvals - number of data values to read
 *
 *  @return
 *    - number of data values successfully read
 *    - -1 if an error occurred
 */
int lton_read_16(int fd, void *data, size_t nvals)
{
    ssize_t bytes_read;
    int     vals_read;

    bytes_read = read(fd, data, 2*nvals);
    if (bytes_read < 0) {

        ERROR( ARMUTILS_LIB_NAME,
            "Could not read data from file: %s\n", strerror(errno));

        return(-1);
    }

    vals_read = bytes_read/2;

#ifdef _BIG_ENDIAN
    {
        uint16_t *dp = (uint16_t *)data;
        int i;

        for (i = 0; i < vals_read; ++i) {
            dp[i] = SWAP_BYTES_16(dp[i]);
        }
    }
#endif

    return(vals_read);
}
Exemple #2
0
Bitmap::Bitmap(const char *fname, const char *data, int len) :
		Object() {
	_fname = fname;

	if (len < 8 || memcmp(data, "BM  F\0\0\0", 8) != 0) {
		if (gDebugLevel == DEBUG_BITMAPS || gDebugLevel == DEBUG_ERROR || gDebugLevel == DEBUG_ALL)
			error("Invalid magic loading bitmap");
	}

	strcpy(_filename, fname);

	int codec = READ_LE_UINT32(data + 8);
//  _paletteIncluded = READ_LE_UINT32(data + 12);
	_numImages = READ_LE_UINT32(data + 16);
	_x = READ_LE_UINT32(data + 20);
	_y = READ_LE_UINT32(data + 24);
//  _transparentColor = READ_LE_UINT32(data + 28);
	_format = READ_LE_UINT32(data + 32);
//  _numBits = READ_LE_UINT32(data + 36);
//  _blueBits = READ_LE_UINT32(data + 40);
//  _greenBits = READ_LE_UINT32(data + 44);
//  _redBits = READ_LE_UINT32(data + 48);
//  _blueShift = READ_LE_UINT32(data + 52);
//  _greenShift = READ_LE_UINT32(data + 56);
//  _redShift = READ_LE_UINT32(data + 60);
	_width = READ_LE_UINT32(data + 128);
	_height = READ_LE_UINT32(data + 132);
	_currImage = 1;

	_data = new char *[_numImages];
	int pos = 0x88;
	for (int i = 0; i < _numImages; i++) {
		_data[i] = new char[2 * _width * _height];
		if (codec == 0) {
			memcpy(_data[i], data + pos, 2 * _width * _height);
			pos += 2 * _width * _height + 8;
		} else if (codec == 3) {
			int compressed_len = READ_LE_UINT32(data + pos);
			decompress_codec3(data + pos + 4, _data[i]);
			pos += compressed_len + 12;
		}

#ifdef SYSTEM_BIG_ENDIAN
		if (_format == 1)
			for (int j = 0; j < _width * _height; ++j) {
				((uint16 *)_data[i])[j] = SWAP_BYTES_16(((uint16 *)_data[i])[j]);
			}
#endif
	}

	g_driver->createBitmap(this);
}
Exemple #3
0
/**
 *  Convert array of 16 bit big endian values to native byte order.
 *
 *  @param  data  - pointer to the array of data values
 *  @param  nvals - number of values in the data array
 *
 *  @return pointer to the array of data values
 */
void *bton_16(void *data, size_t nvals)
{
#ifndef _BIG_ENDIAN
    uint16_t *dp = (uint16_t *)data;
    size_t    i;

    for (i = 0; i < nvals; ++i) {
        dp[i] = SWAP_BYTES_16(dp[i]);
    }

#endif
    return(data);
}
void OpenGLTexture::byteswapSurface(Graphics::Surface *surface) {
	for (int y = 0; y < surface->h; y++) {
		for (int x = 0; x < surface->w; x++) {
			if (surface->format.bytesPerPixel == 4) {
				uint32 *pixel = (uint32 *) (surface->getBasePtr(x, y));
				*pixel = SWAP_BYTES_32(*pixel);
			} else if (surface->format.bytesPerPixel == 2) {
				uint16 *pixel = (uint16 *) (surface->getBasePtr(x, y));
				*pixel = SWAP_BYTES_16(*pixel);
			} else {
				error("Unexpected bytes per pixedl %d", surface->format.bytesPerPixel);
			}
		}
	}
}
Exemple #5
0
bool SaveConverter::swapDataEndian(byte *data, const byte *sizes, uint32 count) {
    if (!data || !sizes || (count == 0))
        return false;

    while (count-- > 0) {
        if      (*sizes == 3) // 32bit value (3 additional bytes)
            WRITE_UINT32(data, SWAP_BYTES_32(READ_UINT32(data)));
        else if (*sizes == 1) // 16bit value (1 additional byte)
            WRITE_UINT16(data, SWAP_BYTES_16(READ_UINT16(data)));
        else if (*sizes != 0) // else, it has to be an 8bit value
            return false;

        count -= *sizes;
        data  += *sizes + 1;
        sizes += *sizes + 1;
    }

    return true;
}
Exemple #6
0
bool BitmapData::loadGrimBm(Common::SeekableReadStream *data) {
	uint32 tag2 = data->readUint32BE();
	if (tag2 != (MKTAG('F','\0','\0','\0')))
		return false;

	int codec = data->readUint32LE();
	data->readUint32LE();               //_paletteIncluded
	_numImages = data->readUint32LE();
	_x = data->readUint32LE();
	_y = data->readUint32LE();
	data->readUint32LE();               //_transparentColor
	_format = data->readUint32LE();
	_bpp = data->readUint32LE();
//  uint32 redBits = data->readUint32LE();
//  uint32 greenBits = data->readUint32LE();
//  uint32 blueBits = data->readUint32LE();
//  uint32 redShift = data->readUint32LE();
//  uint32 greenShift = data->readUint32LE();
//  uint32 blueShift = data->readUint32LE();

	// Hardcode the format, since the values saved in the files are garbage for some, like "ha_0_elvos.zbm".
	Graphics::PixelFormat pixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);

	data->seek(128, SEEK_SET);
	_width = data->readUint32LE();
	_height = data->readUint32LE();
	_colorFormat = BM_RGB565;
	_hasTransparency = false;

	_data = new Graphics::PixelBuffer[_numImages];
	data->seek(0x80, SEEK_SET);
	for (int i = 0; i < _numImages; i++) {
		data->seek(8, SEEK_CUR);
		_data[i].create(pixelFormat, _width * _height, DisposeAfterUse::YES);
		if (codec == 0) {
			uint32 dsize = _bpp / 8 * _width * _height;
			data->read(_data[i].getRawBuffer(), dsize);
		} else if (codec == 3) {
			int compressed_len = data->readUint32LE();
			char *compressed = new char[compressed_len];
			data->read(compressed, compressed_len);
			bool success = decompress_codec3(compressed, (char *)_data[i].getRawBuffer(), _bpp / 8 * _width * _height);
			delete[] compressed;
			if (!success)
				warning(".. when loading image %s.\n", _fname.c_str());
		} else
			Debug::error(Debug::Bitmaps, "Unknown image codec in BitmapData ctor!");

#ifdef SCUMM_BIG_ENDIAN
		if (_format == 1) {
			uint16 *d = (uint16 *)_data[i].getRawBuffer();
			for (int j = 0; j < _width * _height; ++j) {
				d[j] = SWAP_BYTES_16(d[j]);
			}
		}
#endif
	}

	// Initially, no GPU-side textures created. the createBitmap
	// function will allocate some if necessary (and successful)
	_numTex = 0;
	_texIds = nullptr;

	g_driver->createBitmap(this);
	return true;
}
Exemple #7
0
void Sound::checkSpeechFileEndianness() {
	// Some mac versions (not all of them) use big endian wav, although
	// the wav header doesn't indicate it.
	// Use heuristic to determine endianness of speech.
	// The heuristic consist in computing the sum of the absolute difference for
	// every two consecutive samples. This is done both with a big endian and a
	// little endian assumption. The one with the smallest sum should be the
	// correct one (the sound wave is supposed to be relatively smooth).
	// It needs at least 1000 samples to get stable result (the code below is
	// using the first 2000 samples of the wav sound).

	// Init speech file if not already done.
	if (!_currentCowFile) {
		// Open one of the speech files. It uses SwordEngine::_systemVars.currentCD
		// to decide which file to open, therefore if it is currently set to zero
		// we have to set it to either 1 or 2 (I decided to set it to 1 as this is
		// more likely to be the first file that will be needed).
		bool no_current_cd = false;
		if (SwordEngine::_systemVars.currentCD == 0) {
			SwordEngine::_systemVars.currentCD = 1;
			no_current_cd = true;
		}
		initCowSystem();
		if (no_current_cd) {
			// In case it fails with CD1 retry with CD2
			if (!_currentCowFile) {
				SwordEngine::_systemVars.currentCD = 2;
				initCowSystem();
			}
			// Reset currentCD flag
			SwordEngine::_systemVars.currentCD = 0;
		}
	}

	// Testing for endianness makes sense only if using the uncompressed files.
	if (_cowHeader == NULL || (_cowMode != CowWave && _cowMode != CowDemo))
		return;

	// I picked the sample to use randomly (I just made sure it is long enough so that there is
	// a fair change of the heuristic to have a stable result and work for every language).
	int roomNo = _currentCowFile == 1 ? 1 : 129;
	int localNo = _currentCowFile == 1 ? 2 : 933;
	// Get the speech data and apply the heuristic
	uint32 locIndex = _cowHeader[roomNo] >> 2;
	uint32 sampleSize = _cowHeader[locIndex + (localNo * 2)];
	uint32 index = _cowHeader[locIndex + (localNo * 2) - 1];
	if (sampleSize) {
		uint32 size;
		double be_diff_sum = 0., le_diff_sum = 0.;
		_bigEndianSpeech = false;
		int16 *data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size);
		// Compute average of difference between two consecutive samples for both BE and LE
		if (data) {
			if (size > 4000)
				size = 2000;
			else
				size /= 2;
			int16 prev_be_value = (int16)SWAP_BYTES_16(*((uint16*)(data)));
			for (uint32 i = 1; i < size; ++i) {
				le_diff_sum += fabs((double)(data[i] - data[i-1]));
				int16 be_value = (int16)SWAP_BYTES_16(*((uint16*)(data + i)));
				be_diff_sum += fabs((double)(be_value - prev_be_value));
				prev_be_value = be_value;
			}
			delete [] data;
		}
		// Set the big endian flag
		_bigEndianSpeech = (be_diff_sum < le_diff_sum);
		if (_bigEndianSpeech)
			debug(6, "Mac version: using big endian speech file");
		else
			debug(6, "Mac version: using little endian speech file");
		debug(8, "Speech endianness heuristic: average = %f for BE and %f for LE, computed on %d samples)", be_diff_sum / (size - 1), le_diff_sum / (size - 1), size);
	}
}
Exemple #8
0
void SmackerDecoder::SmackerAudioTrack::queueCompressedBuffer(byte *buffer, uint32 bufferSize, uint32 unpackedSize) {
	Common::BitStream8LSB audioBS(new Common::MemoryReadStream(buffer, bufferSize), true);
	bool dataPresent = audioBS.getBit();

	if (!dataPresent)
		return;

	bool isStereo = audioBS.getBit();
	assert(isStereo == _audioInfo.isStereo);
	bool is16Bits = audioBS.getBit();
	assert(is16Bits == _audioInfo.is16Bits);

	int numBytes = 1 * (isStereo ? 2 : 1) * (is16Bits ? 2 : 1);

	byte *unpackedBuffer = (byte *)malloc(unpackedSize);
	byte *curPointer = unpackedBuffer;
	uint32 curPos = 0;

	SmallHuffmanTree *audioTrees[4];
	for (int k = 0; k < numBytes; k++)
		audioTrees[k] = new SmallHuffmanTree(audioBS);

	// Base values, stored as big endian

	int32 bases[2];

	if (isStereo) {
		if (is16Bits) {
			bases[1] = SWAP_BYTES_16(audioBS.getBits(16));
		} else {
			bases[1] = audioBS.getBits(8);
		}
	}

	if (is16Bits) {
		bases[0] = SWAP_BYTES_16(audioBS.getBits(16));
	} else {
		bases[0] = audioBS.getBits(8);
	}

	// The bases are the first samples, too
	for (int i = 0; i < (isStereo ? 2 : 1); i++, curPointer += (is16Bits ? 2 : 1), curPos += (is16Bits ? 2 : 1)) {
		if (is16Bits)
			WRITE_BE_UINT16(curPointer, bases[i]);
		else
			*curPointer = (bases[i] & 0xFF) ^ 0x80;
	}

	// Next follow the deltas, which are added to the corresponding base values and
	// are stored as little endian
	// We store the unpacked bytes in big endian format

	while (curPos < unpackedSize) {
		// If the sample is stereo, the data is stored for the left and right channel, respectively
		// (the exact opposite to the base values)
		if (!is16Bits) {
			for (int k = 0; k < (isStereo ? 2 : 1); k++) {
				bases[k] += (int8) ((int16) audioTrees[k]->getCode(audioBS));
				*curPointer++ = CLIP<int>(bases[k], 0, 255) ^ 0x80;
				curPos++;
			}
		} else {
			for (int k = 0; k < (isStereo ? 2 : 1); k++) {
				byte lo = audioTrees[k * 2]->getCode(audioBS);
				byte hi = audioTrees[k * 2 + 1]->getCode(audioBS);
				bases[k] += (int16) (lo | (hi << 8));

				WRITE_BE_UINT16(curPointer, bases[k]);
				curPointer += 2;
				curPos += 2;
			}
		}

	}

	for (int k = 0; k < numBytes; k++)
		delete audioTrees[k];

	queuePCM(unpackedBuffer, unpackedSize);
}