Ticket #8437: nut_codec44.diff

File nut_codec44.diff, 10.5 KB (added by cyxx, 16 years ago)

Patch against a June 16 CVS snapshot

  • scumm/nut_renderer.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/nut_renderer.cpp,v
    retrieving revision 1.57
    diff -u -r1.57 nut_renderer.cpp
     
    4444        }
    4545}
    4646
    47 int32 NutRenderer::decodeCodec44(byte *dst, const byte *src, uint32 length) {
    48         byte val;
    49         uint16 size_line, num;
    50         int16 decoded_length = 0;
    51 
    52         do {
    53                 size_line = READ_LE_UINT16(src);
    54                 src += 2;
    55                 length -= 2;
    56 
    57                 while (size_line != 0) {
    58                         num = *src++;
    59                         val = *src++;
    60                         memset(dst, val, num);
    61                         dst += num;
    62                         decoded_length += num;
    63                         length -= 2;
    64                         size_line -= 2;
    65                         if (size_line != 0) {
    66                                 num = READ_LE_UINT16(src) + 1;
    67                                 src += 2;
    68                                 memcpy(dst, src, num);
    69                                 dst += num;
    70                                 decoded_length += num;
    71                                 src += num;
    72                                 length -= num + 2;
    73                                 size_line -= num + 2;
    74                         }
    75                 }
    76                 dst--;
    77                 decoded_length--;
     47static uint8 *fobj_end = 0;
     48static uint8 *dst_end = 0;
    7849
    79         } while (length > 1);
    80         return decoded_length;
    81 }
     50void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch);
    8251
    83 static int32 codec1(byte *dst, byte *src, int height) {
    84         byte val, code;
    85         int32 length, decoded_length = 0;
    86         int h = height, size_line;
    87 
    88         for (h = 0; h < height; h++) {
    89                 size_line = READ_LE_UINT16(src);
    90                 src += 2;
    91                 while (size_line > 0) {
    92                         code = *src++;
    93                         size_line--;
    94                         length = (code >> 1) + 1;
    95                         if (code & 1) {
    96                                 val = *src++;
    97                                 size_line--;
    98                                 if (val)
    99                                         memset(dst, val, length);
    100                                 dst += length;
    101                                 decoded_length += length;
    102                         } else {
    103                                 size_line -= length;
    104                                 while (length--) {
    105                                         val = *src++;
    106                                         if (val)
    107                                                 *dst = val;
    108                                         dst++;
    109                                         decoded_length++;
    110                                 }
     52static void smush_decode_codec21(byte *dst, const byte *src, int width, int height, int pitch) {
     53        while (height--) {
     54                uint8 *dstPtrNext = dst + pitch;
     55                assert(src + 2 <= fobj_end);
     56                const uint8 *srcPtrNext = src + 2 + READ_LE_UINT16(src); src += 2;
     57                int len = width;
     58                do {
     59                        assert(src + 2 <= fobj_end);
     60                        int offs = READ_LE_UINT16(src); src += 2;
     61                        dst += offs;
     62                        len -= offs;
     63                        if (len <= 0) {
     64                                break;
    11165                        }
    112                 }
     66                        assert(src + 2 <= fobj_end);
     67                        int w = READ_LE_UINT16(src) + 1; src += 2;
     68                        len -= w;
     69                        if (len < 0) {
     70                                w += len;
     71                        }
     72                        // the original codec44 handles this part slightly differently (this is the only difference with codec21) :
     73                        //  src bytes equal to 255 are replaced by 0 in dst
     74                        //  src bytes equal to 1 are replaced by a color passed as an argument in the original function
     75                        //  other src bytes values are copied as-is
     76                        assert(dst + w <= dst_end);
     77                        assert(src + w <= fobj_end);
     78                        memcpy(dst, src, w); dst += w; src += w;
     79                } while (len > 0);
     80                dst = dstPtrNext;
     81                src = srcPtrNext;
    11382        }
    114         return decoded_length;
    11583}
    11684
    11785bool NutRenderer::loadFont(const char *filename) {
     
    145113
    146114        _numChars = READ_LE_UINT16(dataSrc + 10);
    147115        uint32 offset = 0;
    148         int32 decoded_length;
    149 
    150116        for (int l = 0; l < _numChars; l++) {
    151117                offset += READ_BE_UINT32(dataSrc + offset + 4) + 8;
    152                 if (READ_BE_UINT32(dataSrc + offset) == 'FRME') {
    153                         offset += 8;
    154 
    155                         if (READ_BE_UINT32(dataSrc + offset) == 'FOBJ') {
    156                                 int codec = READ_LE_UINT16(dataSrc + offset + 8);
    157                                 _chars[l].xoffs = READ_LE_UINT16(dataSrc + offset + 10);
    158                                 _chars[l].yoffs = READ_LE_UINT16(dataSrc + offset + 12);
    159                                 _chars[l].width = READ_LE_UINT16(dataSrc + offset + 14);
    160                                 _chars[l].height = READ_LE_UINT16(dataSrc + offset + 16);
    161                                 _chars[l].src = new byte[(_chars[l].width + 2) * _chars[l].height + 1000];
    162 
    163                                 // If characters have transparency, then bytes just get skipped and
    164                                 // so there may appear some garbage. That's why we have to fill it
    165                                 // with zeroes first.
    166                                 memset(_chars[l].src, 0, (_chars[l].width + 2) * _chars[l].height + 1000);
    167                                 if ((codec == 44) || (codec == 21))
    168                                         decoded_length = decodeCodec44(_chars[l].src, dataSrc + offset + 22, READ_BE_UINT32(dataSrc + offset + 4) - 14);
    169                                 else if (codec == 1) {
    170                                         decoded_length = codec1(_chars[l].src, dataSrc + offset + 22, _chars[l].height);
    171                                 } else
    172                                         error("NutRenderer::loadFont: unknown codec: %d", codec);
    173 
    174                                 // FIXME: This is used to work around wrong font file format in Russian
    175                                 // version of FT. Font files there contain wrong information about
    176                                 // glyphs width. See patch #823031.
    177                                 if (_vm->_language == Common::RU_RUS) {
    178                                         // try to rely on length of returned data
    179                                         if (l > 127)
    180                                                 _chars[l].width = decoded_length / _chars[l].height;
    181                                         // but even this not always works
    182                                         if (l == 134 && !strcmp(filename, "titlfnt.nut"))
    183                                                 _chars[l].width--;
    184                                 }
    185                         } else {
    186                                 warning("NutRenderer::loadFont(%s) there is no FOBJ chunk in FRME chunk %d (offset %x)", filename, l, offset);
    187                                 break;
    188                         }
    189                 } else {
     118                if (READ_BE_UINT32(dataSrc + offset) != 'FRME') {
    190119                        warning("NutRenderer::loadFont(%s) there is no FRME chunk %d (offset %x)", filename, l, offset);
    191120                        break;
    192121                }
     122                offset += 8;
     123                if (READ_BE_UINT32(dataSrc + offset) != 'FOBJ') {
     124                        warning("NutRenderer::loadFont(%s) there is no FOBJ chunk in FRME chunk %d (offset %x)", filename, l, offset);
     125                        break;
     126                }
     127                int codec = READ_LE_UINT16(dataSrc + offset + 8);
     128                _chars[l].xoffs = READ_LE_UINT16(dataSrc + offset + 10);
     129                _chars[l].yoffs = READ_LE_UINT16(dataSrc + offset + 12);
     130                _chars[l].width = READ_LE_UINT16(dataSrc + offset + 14);
     131                _chars[l].height = READ_LE_UINT16(dataSrc + offset + 16);
     132                const int srcSize = _chars[l].width * _chars[l].height;
     133                _chars[l].src = new byte[srcSize];
     134                // If characters have transparency, then bytes just get skipped and
     135                // so there may appear some garbage. That's why we have to fill it
     136                // with zeroes first.
     137                memset(_chars[l].src, 0, srcSize);
     138               
     139                const uint8 *fobjptr = dataSrc + offset + 22;
     140                fobj_end = dataSrc + offset + 22 + READ_BE_UINT32(dataSrc + offset + 4) - 14;
     141                dst_end = _chars[l].src + srcSize;
     142                switch (codec) {
     143                case 1:
     144                        smush_decode_codec1(_chars[l].src, fobjptr, 0, 0, _chars[l].width, _chars[l].height, _chars[l].width);
     145                        break;
     146                case 21:
     147                case 44:
     148                        smush_decode_codec21(_chars[l].src, fobjptr, _chars[l].width, _chars[l].height, _chars[l].width);
     149                        break;
     150                default:
     151                        error("NutRenderer::loadFont: unknown codec: %d", codec);
     152                }
    193153        }
    194154
    195155        free(dataSrc);
     
    227187        return _chars[c].height;
    228188}
    229189
    230 int NutRenderer::getCharOffsX(byte c) const {
    231         if (!_loaded) {
    232                 warning("NutRenderer::getCharOffsX() Font is not loaded");
    233                 return 0;
    234         }
    235 
    236         if (c >= 0x80 && _vm->_useCJKMode) {
    237                 return 0;
    238         }
    239 
    240         if (c >= _numChars)
    241                 error("invalid character in NutRenderer::getCharOffsX : %d (%d)", c, _numChars);
    242 
    243         return _chars[c].xoffs;
    244 }
    245 
    246 int NutRenderer::getCharOffsY(byte c) const {
    247         if (!_loaded) {
    248                 warning("NutRenderer::getCharOffsY() Font is not loaded");
    249                 return 0;
    250         }
    251 
    252         if (c >= 0x80 && _vm->_useCJKMode) {
    253                 return 0;
    254         }
    255 
    256         if (c >= _numChars)
    257                 error("invalid character in NutRenderer::getCharOffsY : %d (%d)", c, _numChars);
    258 
    259         return _chars[c].yoffs;
    260 }
    261 
    262190void NutRenderer::drawShadowChar(const Graphics::Surface &s, int c, int x, int y, byte color, bool showShadow) {
    263191        if (!_loaded) {
    264192                warning("NutRenderer::drawShadowChar() Font is not loaded");
  • scumm/nut_renderer.h

    RCS file: /cvsroot/scummvm/scummvm/scumm/nut_renderer.h,v
    retrieving revision 1.22
    diff -u -r1.22 nut_renderer.h
     
    4242                byte *src;
    4343        } _chars[256];
    4444
    45         int32 decodeCodec44(byte *dst, const byte *src, uint32 length);
    46 
    4745        void drawChar(const Graphics::Surface &s, byte c, int x, int y, byte color);
    4846        void draw2byte(const Graphics::Surface &s, int c, int x, int y, byte color);
    4947
     
    5957
    6058        int getCharWidth(byte c) const;
    6159        int getCharHeight(byte c) const;
    62 
    63         int getCharOffsX(byte c) const;
    64         int getCharOffsY(byte c) const;
    6560};
    6661
    6762} // End of namespace Scumm
  • scumm/smush/codec1.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/smush/codec1.cpp,v
    retrieving revision 1.15
    diff -u -r1.15 codec1.cpp
     
    2424
    2525namespace Scumm {
    2626
    27 void smush_decode_codec1(byte *dst, byte *src, int left, int top, int height, int width, int dstWidth) {
     27void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch) {
    2828        byte val, code;
    2929        int32 length;
    3030        int h = height, size_line;
    3131
    32         dst += top * dstWidth;
     32        dst += top * pitch;
    3333        for (h = 0; h < height; h++) {
    3434                size_line = READ_LE_UINT16(src);
    3535                src += 2;
     
    5454                                }
    5555                        }
    5656                }
    57                 dst += dstWidth - left - width;
     57                dst += pitch - left - width;
    5858        }
    5959}
    6060
  • scumm/smush/smush_player.cpp

    RCS file: /cvsroot/scummvm/scummvm/scumm/smush/smush_player.cpp,v
    retrieving revision 1.165
    diff -u -r1.165 smush_player.cpp
     
    724724        setDirtyColors(0, 255);
    725725}
    726726
    727 void smush_decode_codec1(byte *dst, byte *src, int left, int top, int height, int width, int dstWidth);
     727void smush_decode_codec1(byte *dst, const byte *src, int left, int top, int width, int height, int pitch);
    728728
    729729#ifdef USE_ZLIB
    730730void SmushPlayer::handleZlibFrameObject(Chunk &b) {
     
    781781        switch (codec) {
    782782        case 1:
    783783        case 3:
    784                 smush_decode_codec1(_dst, fobjBuffer + 14, left, top, height, width, _vm->_screenWidth);
     784                smush_decode_codec1(_dst, fobjBuffer + 14, left, top, width, height, _vm->_screenWidth);
    785785                break;
    786786        case 37:
    787787                _codec37.decode(_dst, fobjBuffer + 14);
     
    855855        switch (codec) {
    856856        case 1:
    857857        case 3:
    858                 smush_decode_codec1(_dst, chunk_buffer, left, top, height, width, _vm->_screenWidth);
     858                smush_decode_codec1(_dst, chunk_buffer, left, top, width, height, _vm->_screenWidth);
    859859                break;
    860860        case 37:
    861861                _codec37.decode(_dst, chunk_buffer);