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

msrle.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 
00025 #include "image/codecs/msrle.h"
00026 #include "common/stream.h"
00027 #include "common/textconsole.h"
00028 
00029 namespace Image {
00030 
00031 MSRLEDecoder::MSRLEDecoder(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 MSRLEDecoder::~MSRLEDecoder() {
00038     _surface->free();
00039     delete _surface;
00040 }
00041 
00042 const Graphics::Surface *MSRLEDecoder::decodeFrame(Common::SeekableReadStream &stream) {
00043     if (_bitsPerPixel == 8) {
00044         decode8(stream);
00045     } else
00046         error("Unhandled %d bit Microsoft RLE encoding", _bitsPerPixel);
00047 
00048     return _surface;
00049 }
00050 
00051 void MSRLEDecoder::decode8(Common::SeekableReadStream &stream) {
00052 
00053     int x = 0;
00054     int y = _surface->h - 1;
00055 
00056     byte *data = (byte *) _surface->getPixels();
00057     uint16 width  = _surface->w;
00058     uint16 height = _surface->h;
00059 
00060     byte *output     = data + ((height - 1) * width);
00061     byte *output_end = data + ((height)     * width);
00062 
00063     while (!stream.eos()) {
00064         byte count = stream.readByte();
00065         byte value = stream.readByte();
00066 
00067         if (count == 0) {
00068             if (value == 0) {
00069                 // End of line
00070 
00071                 x = 0;
00072                 y--;
00073                 output = data + (y * width);
00074 
00075             } else if (value == 1) {
00076                 // End of image
00077                 return;
00078 
00079             } else if (value == 2) {
00080                 // Skip
00081 
00082                 count = stream.readByte();
00083                 value = stream.readByte();
00084 
00085                 y -= value;
00086                 x += count;
00087 
00088                 if (y < 0) {
00089                     warning("MS RLE Codec: Skip beyond picture bounds");
00090                     return;
00091                 }
00092 
00093                 output = data + ((y * width) + x);
00094 
00095             } else {
00096                 // Copy data
00097                 if (y < 0) {
00098                     warning("MS RLE Codec: Copy data is beyond picture bounds");
00099                     return;
00100                 }
00101 
00102                 if (output + value > output_end) {
00103                     if (stream.pos() + value >= stream.size())
00104                         break;
00105                     else
00106                         stream.skip(value);
00107                     continue;
00108                 }
00109 
00110                 for (int i = 0; i < value; i++)
00111                     *output++ = stream.readByte();
00112 
00113                 if (value & 1)
00114                     stream.skip(1);
00115 
00116                 x += value;
00117             }
00118 
00119         } else {
00120             // Run data
00121             if (y < 0) {
00122                 warning("MS RLE Codec: Run data is beyond picture bounds");
00123                 return;
00124             }
00125 
00126             if (output + count > output_end)
00127                 continue;
00128 
00129             for (int i = 0; i < count; i++, x++)
00130                 *output++ = value;
00131         }
00132 
00133     }
00134 
00135     warning("MS RLE Codec: No end-of-picture code");
00136 }
00137 
00138 } // End of namespace Image


Generated on Sat Apr 20 2019 05:03:16 for ResidualVM by doxygen 1.7.1
curved edge   curved edge