ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

msrle4.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 // Based off ffmpeg's msrledec.c
00024 #include "common/debug.h"
00025 #include "image/codecs/msrle4.h"
00026 #include "common/stream.h"
00027 #include "common/textconsole.h"
00028 #include "common/util.h"
00029 namespace Image {
00030 
00031 MSRLE4Decoder::MSRLE4Decoder(uint16 width, uint16 height, byte bitsPerPixel) {
00032     _surface = new Graphics::Surface();
00033     _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
00034     _bitsPerPixel = bitsPerPixel;
00035 }
00036 
00037 MSRLE4Decoder::~MSRLE4Decoder() {
00038     _surface->free();
00039     delete _surface;
00040 }
00041 
00042 const Graphics::Surface *MSRLE4Decoder::decodeFrame(Common::SeekableReadStream &stream) {
00043     if (_bitsPerPixel == 4) {
00044         decode4(stream);
00045     } else
00046         error("Unhandled %d bit Microsoft RLE encoding", _bitsPerPixel);
00047 
00048     return _surface;
00049 }
00050 
00051 void MSRLE4Decoder::decode4(Common::SeekableReadStream &stream) {
00052     int x = 0;
00053     int y = _surface->h - 1;
00054 
00055     byte *output     = (byte *)_surface->getBasePtr(x, y);
00056     byte *output_end = (byte *)_surface->getBasePtr(_surface->w, y);
00057 
00058     while (!stream.eos()) {
00059         byte count = stream.readByte();
00060 
00061         if (count == 0) {
00062             byte value = stream.readByte();
00063 
00064             if (value == 0) {
00065                 // End of line
00066 
00067                 x = 0;
00068                 y--;
00069                 output = (byte *)_surface->getBasePtr(x, y);
00070             } else if (value == 1) {
00071                 // End of image
00072 
00073                 return;
00074             } else if (value == 2) {
00075                 // Skip
00076 
00077                 count = stream.readByte();
00078                 value = stream.readByte();
00079 
00080                 x += count;
00081                 y -= value;
00082 
00083                 if (y < 0) {
00084                     warning("MS RLE Codec: Skip beyond picture bounds");
00085                     return;
00086                 }
00087 
00088                 output = (byte *)_surface->getBasePtr(x, y);
00089 
00090             } else {
00091                 // Copy data
00092 
00093                 int odd_pixel = value & 1;
00094                 int rle_code = (value + 1) / 2;
00095                 int extra_byte = rle_code & 0x01;
00096 
00097                 if (output + value > output_end) {
00098                     stream.skip(rle_code + extra_byte);
00099                     continue;
00100                 }
00101 
00102                 for (int i = 0; i < rle_code; i++) {
00103                     byte color = stream.readByte();
00104                     *output++ = (color & 0xf0) >> 4;
00105                     if (i + 1 == rle_code && odd_pixel) {
00106                         break;
00107                     }
00108                     *output++ = color & 0x0f;
00109                 }
00110 
00111                 if (extra_byte)
00112                     stream.skip(1);
00113 
00114                 x += value;
00115             }
00116 
00117         } else {
00118             // Run data
00119 
00120             if (output + count > output_end)
00121                 continue;
00122 
00123             byte color = stream.readByte();
00124 
00125             for (int i = 0; i < count; i++, x++) {
00126                 *output++ = (color & 0xf0) >> 4;
00127                 i++;
00128                 x++;
00129                 if (i == count)
00130                     break;
00131                 *output++ = color & 0x0f;
00132             }
00133         }
00134 
00135     }
00136 
00137     warning("MS RLE Codec: No end-of-picture code");
00138 }
00139 
00140 } // End of namespace Image


Generated on Sat Mar 16 2019 05:01:47 for ResidualVM by doxygen 1.7.1
curved edge   curved edge