From 15318cad33835e4e2dc620d033e43cd930676cdd Mon Sep 17 00:00:00 2001 From: kergoth Date: Fri, 25 Jan 2002 22:14:26 +0000 Subject: Initial revision --- (limited to 'core/multimedia/opieplayer/libflash') diff --git a/core/multimedia/opieplayer/libflash/Makefile.in b/core/multimedia/opieplayer/libflash/Makefile.in new file mode 100644 index 0000000..52c8557 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/Makefile.in @@ -0,0 +1,644 @@ +############################################################################# + +####### Compiler, tools and options + +CXX = $(SYSCONF_CXX) $(QT_CXX_MT) +CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) +CC = $(SYSCONF_CC) $(QT_C_MT) +CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) +INCPATH = -I$(QPEDIR)/include +LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT) +LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP) +MOC = $(SYSCONF_MOC) +UIC = $(SYSCONF_UIC) + +####### Target + +DESTDIR = ../../plugins/codecs/ +VER_MAJ = 1 +VER_MIN = 0 +VER_PATCH = 0 +TARGET = flashplugin +TARGET1 = lib$(TARGET).so.$(VER_MAJ) + +####### Files + +HEADERS = libflashplugin.h \ + libflashpluginimpl.h +SOURCES = libflashplugin.cpp \ + libflashpluginimpl.cpp \ + adpcm.cc \ + character.cc \ + flash.cc \ + graphic16.cc \ + matrix.cc \ + script.cc \ + sprite.cc \ + bitmap.cc \ + cxform.cc \ + font.cc \ + graphic24.cc \ + movie.cc \ + shape.cc \ + sqrt.cc \ + button.cc \ + displaylist.cc \ + graphic.cc \ + graphic32.cc \ + program.cc \ + sound.cc \ + text.cc +OBJECTS = libflashplugin.o \ + libflashpluginimpl.o \ + adpcm.o \ + character.o \ + flash.o \ + graphic16.o \ + matrix.o \ + script.o \ + sprite.o \ + bitmap.o \ + cxform.o \ + font.o \ + graphic24.o \ + movie.o \ + shape.o \ + sqrt.o \ + button.o \ + displaylist.o \ + graphic.o \ + graphic32.o \ + program.o \ + sound.o \ + text.o +INTERFACES = +UICDECLS = +UICIMPLS = +SRCMOC = +OBJMOC = + + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + + +all: $(DESTDIR)$(SYSCONF_LINK_TARGET) + +$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) + $(SYSCONF_LINK_LIB) + +moc: $(SRCMOC) + +tmake: Makefile.in + +Makefile.in: libflash.pro + tmake libflash.pro -o Makefile.in + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS) + -rm -f *~ core + -rm -f allmoc.cpp + +####### Extension Modules + +listpromodules: + @echo + +listallmodules: + @echo + +listaddonpromodules: + @echo + +listaddonentmodules: + @echo + + +REQUIRES= + +####### Sub-libraries + + +###### Combined headers + + + +####### Compile + +libflashplugin.o: libflashplugin.cpp \ + libflashplugin.h \ + flash.h \ + ../mediaplayerplugininterface.h + +libflashpluginimpl.o: libflashpluginimpl.cpp \ + libflashplugin.h \ + flash.h \ + ../mediaplayerplugininterface.h \ + libflashpluginimpl.h \ + ../mediaplayerplugininterface.h + +adpcm.o: adpcm.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +character.o: character.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +flash.o: flash.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h \ + graphic16.h \ + graphic24.h \ + graphic32.h + +graphic16.o: graphic16.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h \ + graphic16.h + +matrix.o: matrix.cc \ + matrix.h + +script.o: script.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +sprite.o: sprite.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +bitmap.o: bitmap.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +cxform.o: cxform.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +font.o: font.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +graphic24.o: graphic24.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h \ + graphic24.h + +movie.o: movie.cc \ + movie.h \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h + +shape.o: shape.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +sqrt.o: sqrt.cc + +button.o: button.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +displaylist.o: displaylist.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +graphic.o: graphic.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +graphic32.o: graphic32.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h \ + graphic32.h + +program.o: program.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +sound.o: sound.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + +text.o: text.cc \ + swf.h \ + flash.h \ + matrix.h \ + cxform.h \ + rect.h \ + jpeglib.h \ + jconfig.h \ + jmorecfg.h \ + jerror.h \ + graphic.h \ + character.h \ + bitmap.h \ + shape.h \ + displaylist.h \ + sound.h \ + button.h \ + font.h \ + text.h \ + adpcm.h \ + program.h \ + sprite.h \ + script.h \ + movie.h + + diff --git a/core/multimedia/opieplayer/libflash/README b/core/multimedia/opieplayer/libflash/README new file mode 100644 index 0000000..9914a00 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/README @@ -0,0 +1,191 @@ + +MODIFICATIONS BY TROLLTECH +-------------------------- + +Oct. 2001 + +Just the Lib directory of the flash library source archive +has been copied in to the QPE CVS tree. For the full source code +to create a KDE screensaver or stand alone player etc, download +the orginal source tar ball from http://www.swift-tools.com/Flash +The files libflashplugin* have been added to wrapper the library +to produce a Qtopia Media Player plugin out of the code. + +John R. + + +INTRODUCTION +------------ + +Jun. 12th 2000 + +This the Version 0.4.10 of the Flash Library for Linux. + +Flash Plugin is under GPL, see COPYING file. + +Provides: +- Lib contains the FlashLib sources. +- Plugin contains plugin sources. +- Player contains the standalone player sources. +- Kflash a Flash KDE screen saver. + +New features: +- Bug fixes. +- 24 and 32 modes supported. +- Flash Library as screen saver (for xcreensaver and KDE). + +To get some information on this library check out the following link : +http://www.swift-tools.com/Flash + +Authors: Olivier Debon + Fabrice Bellard + +FEATURES +-------- + +Limitations : + - The plugin and the player use XShm extensions, so remote display is not possible. + - No Flash 4 features (but no crash on Flash 4 files). + +Not functional : + - No Morphing. + - No vertical anti-aliasing. + +SOUND SUPPORT +------------- + +Limitations : + - No streamed sound supported (interleaved data). + - No sound envelop. So no fading or balancing effect. + +But the main feature is here and sound can be enjoyed. + +I recommend OSS drivers, but it is not required at all +(http://www.opensound.com) + +If you have troubles with sound put the -DNOSOUND option +for compilation. Also do this for non-Linux Unix. + +THE PLAYER +---------- + +The standalone player can simply control movie by +pressing Q to quit, P to pause, C to continue and +R to replay. +There is also the possibility to zoom in or out +and scroll using Keypad +/- and cursor keys, but +it is buggy on frozen images. + +THE SCREEN SAVERS +----------------- + +The standalone player can be run though xscreensaver. Modify +your .xscreensaver file to add swfplayer: +programs: swfplayer -root /home/olivier/Flash/Test/test.swf +(See xscreensaver doc for more details on Xscreensaver). + +For KDE, just install the kflash.kss file from the Kflash +directory in /usr/bin (or where your KDE installation expects +kss file to be). +In your KDE start menu, select Settings->Desktop->Screensaver +Choose 'Flash Movies' and click on SetUp button. You'll have +to select a Flash file (take the test.swf file provided with +this distribution). The fullscreen option will scale the movie +to the entire screen (it can be very CPU intensive). The +enable sound option will allow to play sounds, but as a screen +saver mode this is not a good idea :) + +BUG REPORT +---------- + +If Netscape crashes when it started to play a Flash file, please +report the complete url where you have found the file. +Do not send the actual file ! + +If you have rendering problem also report the url. + +If the plugin does not seem to show anything or does not do what it +is supposed to do, please consider that the plugin does not support +all Flash 2/4 features. Anyway it tries to play it but may fail then. + +COMPILATION +----------- + +If you use Linux just type 'make'. + +Warning : the plugin compilation should not fail, but you may +have problem with Netscape at startup. See INSTALLATION section +for workarounds. + +For other Unices like FreeBSD or Solaris you may have to change +some flags. See Plugin/Makefile for hints. + +INSTALLATION +------------ + +Once you have successfully compiled the plugin, put the file +npflash.so (located in the Plugin directory) into your +~/.netscape/plugins directory or into the system-wide +/opt/netscape/plugins directory (depends on where you have installed +Netscape). + +If Netscape already runs type 'javascript:navigator.plugins.refresh' +in the Location field. + + PROBLEMS + -------- + +If you have problem to successfully install the plugin, please +read the following hints. Otherwise, report the problem with full +description of your configuration : +- Distribution. +- Compiler. +- Libs (the output of ldconfig -p is useful). +- The netscape version and the output of 'ldd netscape'. + +If some symbols like _rtti or _throw are unresolved, it seems +that you have egcs. Just uncomment the proper line in the main +Makefile. +You may then still have some unresolved symbols like __sigsetjmp. +This time, add -DC6R5 in the Plugin/Makefile at the PLUGIN_DEFINES +line. + + CHECKING + -------- + +To verify that the plugin is installed properly, type "about:plugins" +in Netscape's "Location:" or "Netsite:" field. The plugin should show +up there, something like + +___________________________________________________________________________ + + Shockwave Flash + + File name: /opt/netscape/plugins/npflash.so + + Flash file player Version 0.4.10 + + Shockwave is a trademark of MacromediaŽ + + Author: Olivier Debon + + --------------------------------------------------------------------------------- +| Mime Type | Description | Suffixes | Enabled | +|--------------------------------+-------------------+-------------+--------------| +| application/futuresplash | Flash Plugin | spl | Yes | +| application/x-shockwave-flash | | swf | Yes | + --------------------------------------------------------------------------------- + +___________________________________________________________________________ + + +If it shows up, but the "Enabled" column says "No", you need to +configure the Flash plugin as a helper application. Go to +Edit/Preferences/Navigator/Applications, and add it as follows: + +Description: Flash Plugin +MIME Type: application/x-shockwave-flash +Suffixes: swf +Handled By: Plug In (select "Shockwave Flash") + +------ diff --git a/core/multimedia/opieplayer/libflash/adpcm.cc b/core/multimedia/opieplayer/libflash/adpcm.cc new file mode 100644 index 0000000..a4bc435 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/adpcm.cc @@ -0,0 +1,235 @@ + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +// This file has been rearranged from the code posted +// on news:forums.macromedia.com by Jonathan Gay. +// Courtesy of Macromedia + +// +// ADPCM tables +// + +static const int indexTable2[2] = { + -1, 2, +}; + +// Is this ok? +static const int indexTable3[4] = { + -1, -1, 2, 4, +}; + +static const int indexTable4[8] = { + -1, -1, -1, -1, 2, 4, 6, 8, +}; + +static const int indexTable5[16] = { + -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16, +}; + +static const int* indexTables[] = { + indexTable2, + indexTable3, + indexTable4, + indexTable5 +}; + +static const int stepsizeTable[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +long +Adpcm::GetBits(int n) +{ + if ( bitPos < n ) FillBuffer(); + + assert(bitPos >= n); + + long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n); + bitPos -= n; + + return v; +} + +long +Adpcm::GetSBits(int n) +{ + if ( bitPos < n ) FillBuffer(); + + assert(bitPos >= n); + + long v = ((long)bitBuf << (32-bitPos)) >> (32-n); + bitPos -= n; + + return v; +} + +// +// The Decompressor +// + +// Constructor +Adpcm::Adpcm(unsigned char *buffer, long isStereo) +{ + stereo = isStereo; + src = buffer; + + nBits = 0; // flag that it is not inited + nSamples = 0; + + bitPos = 0; + bitBuf = 0; +} + +void +Adpcm::FillBuffer() +{ + while ( bitPos <= 24 /*&& srcSize > 0*/ ) { + bitBuf = (bitBuf<<8) | *src++; + bitPos += 8; + } +} + +void +Adpcm::Decompress(short *dst, long n) +{ + if ( nBits == 0 ) { + // Get the compression header + nBits = (int)GetBits(2)+2; + } + + const int* indexTable = indexTables[nBits-2]; + int k0 = 1 << (nBits-2); + int signmask = 1 << (nBits-1); + + if ( !stereo ) { + // Optimize for mono + long vp = valpred[0]; // maybe these can get into registers... + int ind = index[0]; + long ns = nSamples; + + while ( n-- > 0 ) { + ns++; + + if ( (ns & 0xFFF) == 1 ) { + // Get a new block header + *dst++ = (short)(vp = GetSBits(16)); + + ind = (int)GetBits(6); // The first sample in a block does not have a delta + } else { + // Process a delta value + int delta = (int)GetBits(nBits); + + // Compute difference and new predicted value + // Computes 'vpdiff = (delta+0.5)*step/4' + int step = stepsizeTable[ind]; + long vpdiff = 0; + int k = k0; + + do { + if ( delta & k ) + vpdiff += step; + step >>= 1; + k >>= 1; + } while ( k ); + + vpdiff += step; // add 0.5 + + if ( delta & signmask ) // the sign bit + vp -= vpdiff; + else + vp += vpdiff; + + // Find new index value + ind += indexTable[delta&(~signmask)]; + + if ( ind < 0 ) + ind = 0; + else if ( ind > 88 ) + ind = 88; + + // clamp output value + if ( vp != (short)vp ) + vp = vp < 0 ? -32768 : 32767; + + /* Step 7 - Output value */ + *dst++ = (short)vp; + } + } + + valpred[0] = vp; + index[0] = ind; + nSamples = ns; + + } else { + int sn = stereo ? 2 : 1; + + // Stereo + while ( n-- > 0 ) { + + nSamples++; + + if ( (nSamples & 0xFFF) == 1 ) { + // Get a new block header + for ( int i = 0; i < sn; i++ ) { + + *dst++ = (short)(valpred[i] = GetSBits(16)); + + // The first sample in a block does not have a delta + index[i] = (int)GetBits(6); + } + } else { + // Process a delta value + for ( int i = 0; i < sn; i++ ) { + int delta = (int)GetBits(nBits); + + // Compute difference and new predicted value + // Computes 'vpdiff = (delta+0.5)*step/4' + + int step = stepsizeTable[index[i]]; + long vpdiff = 0; + int k = k0; + + do { + if ( delta & k ) vpdiff += step; + step >>= 1; + k >>= 1; + } while ( k ); + vpdiff += step; // add 0.5 + + + if ( delta & signmask ) // the sign bit + valpred[i] -= vpdiff; + else + valpred[i] += vpdiff; + + // Find new index value + index[i] += indexTable[delta&(~signmask)]; + + if ( index[i] < 0 ) + index[i] = 0; + else if ( index[i] > 88 ) + index[i] = 88; + + // clamp output value + if ( valpred[i] != (short)valpred[i] ) + valpred[i] = valpred[i] < 0 ? -32768 : 32767; + + /* Step 7 - Output value */ + *dst++ = (short)valpred[i]; + } + } + } + } +} diff --git a/core/multimedia/opieplayer/libflash/adpcm.h b/core/multimedia/opieplayer/libflash/adpcm.h new file mode 100644 index 0000000..5714c0c --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/adpcm.h @@ -0,0 +1,36 @@ +#ifndef _ADPCM_H_ +#define _ADPCM_H_ + +class Adpcm { + + // Destination format - note we always decompress to 16 bit + long stereo; + int nBits; // number of bits in each sample + + long valpred[2]; // Current state + int index[2]; + + long nSamples; // number of samples decompressed so far + + // Parsing Info + unsigned char *src; + long bitBuf; // this should always contain at least 24 bits of data + int bitPos; + + void FillBuffer(); + + long GetBits(int n); + + long GetSBits(int n); + +public: + Adpcm(unsigned char *buffer, long isStereo); + + void Decompress(short * dst, long n); // return number of good samples +#ifdef DUMP + void dump(BitStream *bs); + void Compress(short *pcm, long n, int bits); +#endif +}; + +#endif /* _ADPCM_H_ */ diff --git a/core/multimedia/opieplayer/libflash/bitmap.cc b/core/multimedia/opieplayer/libflash/bitmap.cc new file mode 100644 index 0000000..03b4588 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/bitmap.cc @@ -0,0 +1,606 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +static unsigned char *inputData; + +// Class variables + +int Bitmap::haveTables = 0; + +struct jpeg_decompress_struct Bitmap::jpegObject; + +struct jpeg_source_mgr Bitmap::jpegSourceManager; + +MyErrorHandler Bitmap::jpegErrorMgr; + +Bitmap::Bitmap(long id, int level) : Character(BitmapType, id ) +{ + pixels = NULL; + alpha_buf = NULL; + colormap = NULL; + nbColors = 0; + defLevel = level; +} + +Bitmap::~Bitmap() +{ + if (pixels) { + delete[] pixels; + } + if (alpha_buf) { + delete[] alpha_buf; + } + if (colormap) + { + delete colormap; + } + if (haveTables) { + jpeg_destroy_decompress(&jpegObject); + haveTables = 0; + } +} + +static void errorExit(j_common_ptr info) +{ + (*info->err->output_message) (info); + longjmp(((MyErrorHandler *)info->err)->setjmp_buffer, 1); +} + +// Methods for Source data manager +static void initSource(struct jpeg_decompress_struct *cInfo) +{ + cInfo->src->bytes_in_buffer = 0; +} + +static boolean fillInputBuffer(struct jpeg_decompress_struct *cInfo) +{ + cInfo->src->next_input_byte = inputData; + cInfo->src->bytes_in_buffer = 1; + inputData++; + + return 1; +} + +static void skipInputData(struct jpeg_decompress_struct *cInfo, long count) +{ + cInfo->src->bytes_in_buffer = 0; + inputData += count; +} + +static boolean resyncToRestart(struct jpeg_decompress_struct *cInfo, int desired) +{ + return jpeg_resync_to_restart(cInfo, desired); +} + +static void termSource(struct jpeg_decompress_struct *cInfo) +{ +} + +long Bitmap::getWidth() +{ + return width; +} + +long Bitmap::getHeight() +{ + return height; +} + +Color * +Bitmap::getColormap(long *n) { + if (n) *n = nbColors; + return colormap; +} + +unsigned char * +Bitmap::getPixels() +{ + return pixels; +} + +// Read Tables and Compressed data to produce an image + +static int +buildJpegAlpha(Bitmap *b, unsigned char *buffer) +{ + z_stream stream; + int status; + unsigned char *data; + + data = new unsigned char[b->width*b->height]; + if (data == NULL) + return -1; + + stream.next_in = buffer; + stream.avail_in = 1; + stream.next_out = data; + stream.avail_out = b->width*b->height; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + + status = inflateInit(&stream); + + while (1) { + status = inflate(&stream, Z_SYNC_FLUSH) ; + if (status == Z_STREAM_END) { + break; + } + if (status != Z_OK) { + printf("Zlib data error : %s\n", stream.msg); + delete data; + return -1; + } + stream.avail_in = 1; + } + + inflateEnd(&stream); + + b->alpha_buf = data; + + return 0; +} + +int +Bitmap::buildFromJpegInterchangeData(unsigned char *stream, int read_alpha, long offset) +{ + struct jpeg_decompress_struct cInfo; + struct jpeg_source_mgr mySrcMgr; + MyErrorHandler errorMgr; + JSAMPROW buffer[1]; + unsigned char *ptrPix; + int stride; + long n; + +#if PRINT&1 + printf("flash: loading jpeg (interchange)\n"); +#endif + + // Kludge to correct some corrupted files + if (stream[1] == 0xd9 && stream[3] == 0xd8) { + stream[3] = 0xd9; + stream[1] = 0xd8; + } + + // Setup error handler + cInfo.err = jpeg_std_error(&errorMgr.pub); + errorMgr.pub.error_exit = errorExit; + + if (setjmp(errorMgr.setjmp_buffer)) { + // JPEG data Error + jpeg_destroy_decompress(&cInfo); + if (pixels) { + delete[] pixels; + pixels = NULL; + } + return -1; + } + + // Set current stream pointer to stream + inputData = stream; + + // Here it's Ok + + jpeg_create_decompress(&cInfo); + + // Setup source manager structure + mySrcMgr.init_source = initSource; + mySrcMgr.fill_input_buffer = fillInputBuffer; + mySrcMgr.skip_input_data = skipInputData; + mySrcMgr.resync_to_restart = resyncToRestart; + mySrcMgr.term_source = termSource; + + // Set default source manager + cInfo.src = &mySrcMgr; + + jpeg_read_header(&cInfo, FALSE); + + jpeg_read_header(&cInfo, TRUE); + cInfo.quantize_colors = TRUE; // Create colormapped image + jpeg_start_decompress(&cInfo); + + // Set objet dimensions + height = cInfo.output_height; + width = cInfo.output_width; + bpl = width; + pixels = new unsigned char [height*width]; + if (pixels == NULL) { + jpeg_finish_decompress(&cInfo); + jpeg_destroy_decompress(&cInfo); + return -1; + } + ptrPix = pixels; + + stride = cInfo.output_width * cInfo.output_components; + + buffer[0] = (JSAMPROW)malloc(stride); + + while (cInfo.output_scanline < cInfo.output_height) { + + jpeg_read_scanlines(&cInfo, buffer, 1); + + memcpy(ptrPix,buffer[0],stride); + + ptrPix+= stride; + } + + free(buffer[0]); + + colormap = new Color[cInfo.actual_number_of_colors]; + if (colormap == NULL) { + delete pixels; + jpeg_finish_decompress(&cInfo); + jpeg_destroy_decompress(&cInfo); + return -1; + } + nbColors = cInfo.actual_number_of_colors; + + for(n=0; n < nbColors; n++) + { + colormap[n].red = cInfo.colormap[0][n]; + colormap[n].green = cInfo.colormap[1][n]; + colormap[n].blue = cInfo.colormap[2][n]; + } + + jpeg_finish_decompress(&cInfo); + jpeg_destroy_decompress(&cInfo); + + if (read_alpha) { + if (buildJpegAlpha(this, stream + offset) < 0) { + return -1; + } + } + return 0; +} + +// Read JPEG image using pre-loaded Tables + +int +Bitmap::buildFromJpegAbbreviatedData(unsigned char *stream) +{ + JSAMPROW buffer[1]; + unsigned char *ptrPix; + int stride; + long n; + int status; + +#if PRINT&1 + printf("flash: loading jpeg (abbreviated)\n"); +#endif + + // Set current stream pointer to stream + inputData = stream; + + // Error handler + if (setjmp(jpegErrorMgr.setjmp_buffer)) { + // JPEG data Error + //jpeg_destroy_decompress(&jpegObject); + if (pixels) { + delete[] pixels; + pixels = NULL; + } + return -1; + } + + // Here it's ok + + jpeg_read_header(&jpegObject, TRUE); + jpegObject.quantize_colors = TRUE; // Create colormapped image + jpeg_start_decompress(&jpegObject); + + // Set objet dimensions + height = jpegObject.output_height; + width = jpegObject.output_width; + bpl = width; + pixels = new unsigned char [height*width]; + if (pixels == NULL) { + jpeg_finish_decompress(&jpegObject); + return -1; + } + ptrPix = pixels; + + stride = jpegObject.output_width * jpegObject.output_components; + + buffer[0] = (JSAMPROW)malloc(stride); + + while (jpegObject.output_scanline < jpegObject.output_height) { + + status = jpeg_read_scanlines(&jpegObject, buffer, 1); + + memcpy(ptrPix,buffer[0],stride); + + ptrPix+= stride; + } + + free(buffer[0]); + + colormap = new Color[jpegObject.actual_number_of_colors]; + if (colormap == NULL) { + jpeg_finish_decompress(&jpegObject); + delete pixels; + return -1; + } + nbColors = jpegObject.actual_number_of_colors; + + for(n=0; n < nbColors; n++) + { + colormap[n].red = jpegObject.colormap[0][n]; + colormap[n].green = jpegObject.colormap[1][n]; + colormap[n].blue = jpegObject.colormap[2][n]; + } + + status = jpeg_finish_decompress(&jpegObject); + + return 0; +} + +// Just init JPEG object and read JPEG Tables + +int +Bitmap::readJpegTables(unsigned char *stream) +{ + if (haveTables) { + //Error, it has already been initialized + return -1; + } + + // Setup error handler + jpegObject.err = jpeg_std_error(&jpegErrorMgr.pub); + jpegErrorMgr.pub.error_exit = errorExit; + + if (setjmp(jpegErrorMgr.setjmp_buffer)) { + // JPEG data Error + jpeg_destroy_decompress(&jpegObject); + return -1; + } + + // Set current stream pointer to stream + inputData = stream; + + // Here it's Ok + + jpeg_create_decompress(&jpegObject); + + // Setup source manager structure + jpegSourceManager.init_source = initSource; + jpegSourceManager.fill_input_buffer = fillInputBuffer; + jpegSourceManager.skip_input_data = skipInputData; + jpegSourceManager.resync_to_restart = resyncToRestart; + jpegSourceManager.term_source = termSource; + + // Set default source manager + jpegObject.src = &jpegSourceManager; + + jpeg_read_header(&jpegObject, FALSE); + + haveTables = 1; + + return 0; +} + +int +Bitmap::buildFromZlibData(unsigned char *buffer, int width, int height, int format, int tableSize, int tableHasAlpha) +{ + z_stream stream; + int status; + unsigned char *data; + int elementSize; + +#if PRINT&1 + printf("flash: loading with zlib\n"); +#endif + + this->width = width; + this->height = height; + this->bpl = width; + + if (tableHasAlpha) { + elementSize = 4; // Cmap is RGBA + } else { + elementSize = 3; // Cmap is RGB + } + + stream.next_in = buffer; + stream.avail_in = 1; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + + tableSize++; + + // Uncompress Color Table + if (format == 3) { + unsigned char *colorTable; + long n; + + // Ajust width for 32 bit padding + width = (width+3)/4*4; + this->width = width; + this->bpl = width; + + depth = 1; + colorTable = new unsigned char[tableSize*elementSize]; + if (colorTable == NULL) { + return -1; + } + + stream.next_out = colorTable; + stream.avail_out = tableSize*elementSize; + + inflateInit(&stream); + + while (1) { + status = inflate(&stream, Z_SYNC_FLUSH); + if (status == Z_STREAM_END) { + break; + } + if (status != Z_OK) { + printf("Zlib cmap error : %s\n", stream.msg); + return -1; + } + stream.avail_in = 1; + // Colormap if full + if (stream.avail_out == 0) { + break; + } + } + + nbColors = tableSize; + + colormap = new Color[nbColors]; + if (colormap == NULL) { + delete colorTable; + return -1; + } + + for(n=0; n < nbColors; n++) { + colormap[n].red = colorTable[n*elementSize+0]; + colormap[n].green = colorTable[n*elementSize+1]; + colormap[n].blue = colorTable[n*elementSize+2]; + if (tableHasAlpha) { + colormap[n].alpha = colorTable[n*elementSize+3]; + } + } + + delete colorTable; + + } else if (format == 4) { + depth = 2; + width = (width+1)/2*2; + this->bpl = width; + } else if (format == 5) { + depth = 4; + } + + data = new unsigned char[depth*width*height]; + if (data == NULL) { + if (colormap) delete colormap; + return -1; + } + + stream.next_out = data; + stream.avail_out = depth*width*height; + + if (format != 3) { + status = inflateInit(&stream); + } + + while (1) { + status = inflate(&stream, Z_SYNC_FLUSH) ; + if (status == Z_STREAM_END) { + break; + } + if (status != Z_OK) { + printf("Zlib data error : %s\n", stream.msg); + delete data; + return -1; + } + stream.avail_in = 1; + } + + inflateEnd(&stream); + + pixels = new unsigned char [height*width]; + if (pixels == NULL) { + if (colormap) delete colormap; + delete data; + return -1; + } + + if (format != 3) { + int n,c; + unsigned char r,g,b,a; + unsigned char *ptr; + + r = g = b = a = 0; /* to supress warnings */ + + nbColors = 0; + colormap = new Color[256]; + if (colormap == NULL) { + delete data; + delete pixels; + return -1; + } + memset(colormap, 0, 256 * sizeof(Color)); + ptr = pixels; + + for(n=0; n < width*height*depth; n+=depth,ptr++) { + + switch (format) { + case 4: + a = 1; + r = (data[n] & 0x78)<<1; + g = ((data[n] & 0x03)<<6) | (data[n+1] & 0xc0)>>2; + b = (data[n+1] & 0x1e)<<3; + break; + case 5: + a = data[n]; + // Reduce color dynamic range + r = data[n+1]&0xe0; + g = data[n+2]&0xe0; + b = data[n+3]&0xe0; + break; + } + for(c=0; c < nbColors; c++) { + if (r == colormap[c].red + && g == colormap[c].green + && b == colormap[c].blue) { + *ptr = c; + break; + } + } + if (c == nbColors) { + if (nbColors == 256) continue; + nbColors++; + if (nbColors == 256) { + //printf("Colormap entries exhausted. After %d scanned pixels\n", n/4); + } + colormap[c].alpha = a; + colormap[c].red = r; + colormap[c].green = g; + colormap[c].blue = b; + *ptr = c; + } + } + } else { + memcpy(pixels, data, width*height); + if (tableHasAlpha) { + int n; + unsigned char *ptr, *alpha; + + alpha_buf = (unsigned char *)malloc(width*height); + ptr = data; + alpha = alpha_buf; + for(n=0; n < width*height; n++, ptr++, alpha++) { + *alpha = colormap[*ptr].alpha; + } + } + } + + delete data; + return 0; +} + diff --git a/core/multimedia/opieplayer/libflash/bitmap.h b/core/multimedia/opieplayer/libflash/bitmap.h new file mode 100644 index 0000000..7925309 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/bitmap.h @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _BITMAP_H_ +#define _BITMAP_H_ + +struct MyErrorHandler { + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; + +class Bitmap : public Character { + public: + long width; + long height; + long bpl; + long depth; + + unsigned char *pixels; // Array of Pixels + Color *colormap; // Array of color definitions + long nbColors; + + unsigned char *alpha_buf; // Array of alpha values (no alpha if NULL) + + int defLevel; + +// Class Variables + + static int haveTables; + static struct jpeg_decompress_struct jpegObject; + static struct jpeg_source_mgr jpegSourceManager; + static MyErrorHandler jpegErrorMgr; + +public: + Bitmap(long id, int level = 1); + ~Bitmap(); + + // JPEG handling methods + int buildFromJpegInterchangeData(unsigned char *stream, int alpha, long offset); // Complete + int buildFromJpegAbbreviatedData(unsigned char *stream); // Abbreviated + + // Class Method + static int readJpegTables(unsigned char *stream); // Tables Only + + // ZLIB handling methods + int buildFromZlibData(unsigned char *buffer, + int width, int height, + int format, int tableSize, int tableHasAlpha); + + long getWidth(); + long getHeight(); + Color *getColormap(long *n); + unsigned char *getPixels(); +}; + +#endif /* _BITMAP_H_ */ diff --git a/core/multimedia/opieplayer/libflash/button.cc b/core/multimedia/opieplayer/libflash/button.cc new file mode 100644 index 0000000..7d8369d --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/button.cc @@ -0,0 +1,328 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +// Contructor + +Button::Button(long id, int level) : Character(ButtonType, id) +{ + defLevel = level; + actionRecords = 0; + buttonRecords = 0; + conditionList = 0; + reset(); + isMenu = 0; + sound[0] = sound[1] = sound[2] = sound[3] = 0; +} + +// Destructor + +Button::~Button() +{ + if (actionRecords) { + ActionRecord *ar,*del; + for(ar = actionRecords; ar;) { + del = ar; + ar = ar->next; + delete del; + } + } + if (buttonRecords) { + ButtonRecord *br,*del; + for(br = buttonRecords; br;) { + del = br; + br = br->next; + if (del->cxform) + delete del->cxform; + delete del; + } + } + if (conditionList) { + Condition *cond,*del; + for(cond = conditionList; cond;) { + ActionRecord *ar,*d; + + for(ar = cond->actions; ar;) { + d = ar; + ar = ar->next; + delete d; + } + + del = cond; + cond = cond->next; + delete del; + } + } +} + +ButtonRecord * +Button::getButtonRecords() +{ + return buttonRecords; +} + +ActionRecord * +Button::getActionRecords() +{ + return actionRecords; +} + +Sound ** +Button::getSounds() +{ + return sound; +} + +Condition * +Button::getConditionList() +{ + return conditionList; +} + +void +Button::setButtonSound(Sound *s, int state) +{ + if (state >=0 && state < 4) { + sound[state] = s; + } +} + +void +Button::setButtonMenu(int menu) +{ + isMenu = menu; +} + +void +Button::addButtonRecord( ButtonRecord *br ) +{ +#if 0 + /* SURTOUT PAS !!! */ + ButtonRecord **l; + + /* sort by layer */ + l=&buttonRecords; + while (*l != NULL && (*l)->layer < br->layer) l = &(*l)->next; + br->next = *l; + *l = br; +#else + br->next = 0; + + if (buttonRecords == 0) { + buttonRecords = br; + } else { + ButtonRecord *current; + + for(current = buttonRecords; current->next; current = current->next); + + current->next = br; + } +#endif +} + +void +Button::addCondition( long transition ) +{ + Condition *condition; + + condition = new Condition; + if (condition == NULL) return; + + condition->transition = transition; + condition->next = conditionList; + + // Move current actionRecords to this condition + condition->actions = actionRecords; + actionRecords = 0; + + conditionList = condition; +} + +void +Button::addActionRecord( ActionRecord *ar ) +{ + ar->next = 0; + + if (actionRecords == 0) { + actionRecords = ar; + } else { + ActionRecord *current; + + for(current = actionRecords; current->next; current = current->next); + + current->next = ar; + } +} + +void +Button::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func) +{ + ButtonRecord *br; + + for (br = buttonRecords; br; br = br->next) + { + if ((br->state & stateHitTest) && br->character /* Temporaire */) { + Matrix mat; + + mat = (*matrix) * br->buttonMatrix; + br->character->getRegion(gd, &mat, id, scan_line_func); + } + } +} + +int +Button::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ButtonState renderState) +{ + ButtonRecord *br; + int sprite = 0; + Cxform *cxf = 0; + +#if PRINT==2 + printf("Rendering Button %d for State(s) ", getTagId()); +#endif + for (br = buttonRecords; br; br = br->next) + { + if ((br->state & renderState) && br->character != NULL) { + Matrix mat; + +#if PRINT==2 + printf("%d ", br->state); +#endif + mat = (*matrix) * br->buttonMatrix; + + if (cxform) { + cxf = cxform; + } else if (br->cxform) { + cxf = br->cxform; + } + + if (br->character->execute(gd, &mat, cxf)) { + sprite = 1; + } + } + } +#if PRINT==2 + printf("\n"); +#endif + return sprite; +} + +ActionRecord * +Button::getActionFromTransition(ButtonState cur, ButtonState old) +{ + Condition *cond; + long mask; + + if (old == cur) return NULL; + + /* transitions */ + mask = 0; + if (old == stateUp && cur == stateOver) + mask |= 0x001; + else if (old == stateOver && cur == stateUp) + mask |= 0x002; + else if (old == stateOver && cur == stateDown) + mask |= 0x004; + else if (old == stateDown && cur == stateOver) + mask |= 0x008; + + if (!isMenu) { + /* push button transitions (XXX: not quite correct) */ + if (old == stateDown && cur == stateUp) + mask = 0x010; + else if (old == stateUp && cur == stateDown) + mask = 0x020; + /* XXX: what is transition 0x040 ?? */ + } else { + /* menu button transitions (XXX: not quite correct) */ + if (old == stateUp && cur == stateDown) + mask = 0x080; + else if (old == stateDown && cur == stateUp) + mask = 0x100; + } + + for (cond = conditionList; cond; cond = cond->next) { + if (cond->transition & mask) { + return cond->actions; + } + } + return 0; +} + +void +Button::getBoundingBox(Rect *bbox, DisplayListEntry *e) +{ + ButtonRecord *br; + + bbox->reset(); + for (br = buttonRecords; br; br = br->next) + { + if (br->state & e->renderState) { + if (br->character) { + Rect bb; + + bb.reset(); + br->character->getBoundingBox(&bb,e); + transformBoundingBox(bbox, &br->buttonMatrix, &bb, 0); + } + } + } +} + +/* Get current render character, actually it should be a list of characters + so a DisplayList after all */ +Character * +Button::getRenderCharacter(ButtonState state) +{ + ButtonRecord *br; + + for (br = buttonRecords; br; br = br->next) + { + if (br->state & state) { + return br->character; + } + } + return 0; +} + +void +Button::updateButtonState(DisplayListEntry *e) +{ + ButtonRecord *br; + + e->buttonCharacter = 0; + for (br = buttonRecords; br; br = br->next) + { + if (br->state & e->renderState) { + e->buttonCharacter = br->character; + e->buttonMatrix = br->buttonMatrix; + return; + } + } +} diff --git a/core/multimedia/opieplayer/libflash/button.h b/core/multimedia/opieplayer/libflash/button.h new file mode 100644 index 0000000..75781b2 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/button.h @@ -0,0 +1,88 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _BUTTON_H_ +#define _BUTTON_H_ + +struct ButtonRecord { + ButtonState state; + Character *character; + long layer; + Matrix buttonMatrix; + Cxform *cxform; + + struct ButtonRecord *next; +}; + +struct Condition { + long transition; + ActionRecord *actions; + + Condition *next; +}; + +class Button : public Character { +public: + long defLevel; + + ButtonRecord *buttonRecords; + ActionRecord *actionRecords; + Condition *conditionList; + + long isMenu; + + Sound *sound[4]; + + Button(long id, int level = 1); + ~Button(); + void addActionRecord( ActionRecord *ar ); + void addButtonRecord( ButtonRecord *br ); + void addCondition( long transition ); + int execute(GraphicDevice *gd, Matrix *matrix, + Cxform *cxform, ButtonState renderState); + ActionRecord *getActionFromTransition(ButtonState currentState, + ButtonState old); + void getRegion(GraphicDevice *gd, Matrix *matrix, + void *id, ScanLineFunc scan_line_func); + ButtonRecord *getButtonRecords(); + void setButtonSound(Sound *, int); + void setButtonMenu(int); + + ActionRecord *getActionRecords(); + Condition *getConditionList(); + Sound **getSounds(); + + void getBoundingBox(Rect *bb, DisplayListEntry *); + + void updateButtonState(DisplayListEntry *); + Character *getRenderCharacter(ButtonState state); + + // Builtin + int isButton() { + return 1; + }; + +#ifdef DUMP + void dump(BitStream *); + void dumpButtonRecords(BitStream *, int putCxform = 0); + void dumpButtonConditions(BitStream *); +#endif +}; + +#endif /* _BUTTON_H_ */ diff --git a/core/multimedia/opieplayer/libflash/character.cc b/core/multimedia/opieplayer/libflash/character.cc new file mode 100644 index 0000000..4b5ce36 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/character.cc @@ -0,0 +1,233 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +///// Character member definitions + +Character::Character(ObjectType objectType, long tagid) +{ + type = objectType; + tagId = tagid; + name = NULL; +} + +Character::~Character() +{ + delete name; +} + +int +Character::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform) +{ + printf("Cannot be executed\n"); + return 0; +} + +ActionRecord * +Character::eventHandler(GraphicDevice *gd, FlashEvent *ev) +{ + fprintf(stderr,"Unable to handle event !!!\n"); + return 0; +} + +int +Character::isButton() +{ + return 0; +} + +int +Character::isSprite(void) +{ + return 0; +} + +char * +Character::getName() +{ + return name; +} + +void +Character::getBoundingBox(Rect *bb, DisplayListEntry *e) +{ + //fprintf(stderr,"Unable to handle getBoundingBox !!!\n"); + bb->xmin = LONG_MAX; + bb->ymin = LONG_MAX; + bb->ymax = LONG_MIN; + bb->ymax = LONG_MIN; + return; +} + +void +Character::getRegion(GraphicDevice *gd, Matrix *matrix, + void *id, ScanLineFunc scan_line_func) +{ + fprintf(stderr,"Unable to handle getRegion !!!\n"); + return; +} + +long +Character::getTagId() +{ + return tagId; +} + +void +Character::reset() +{ +} + +ObjectType +Character::getType() +{ + return type; +} + +char * +Character::getTypeString() +{ + switch (type) { + case BitmapType: + return "Bitmap"; + case FontType: + return "Font"; + case ButtonType: + return "Button"; + case SpriteType: + return "Sprite"; + case ShapeType: + return "Shape"; + case SoundType: + return "Sound"; + case TextType: + return "Text"; + default: + return "Unknown"; + } +} + +void +Character::setName(char* string) +{ + name = strdup(string); +} + +///// Dict methods definitions + +Dict::Dict() +{ + head = 0; +} + +Dict::~Dict() +{ + struct sCharCell *cell,*del; + + for(cell = head; cell;) + { + del = cell; + cell = cell->next; + delete del->elt; + delete del; + } +} + +void +Dict::addCharacter(Character *character) +{ + struct sCharCell *cell; + + cell = new sCharCell; + if (cell == NULL) { + delete character; + return; + } + cell->elt = character; + cell->next = head; + + head = cell; +} + +Character * +Dict::getCharacter(long id) +{ + struct sCharCell *cell; + + for(cell = head; cell; cell = cell->next) + { + if (id == cell->elt->getTagId()) return cell->elt; + } + return 0; +} + +void +Dict::dictRewind() +{ + currentCell = head; +} + +Character * +Dict::dictNextCharacter() +{ + if (currentCell) { + struct sCharCell *cell; + + cell = currentCell; + currentCell = currentCell->next; + return cell->elt; + } else { + return 0; + } +} + +void +Dict::nameCharacter(long id, char *string) +{ + struct sCharCell *cell; + + for(cell = head; cell; cell = cell->next) + { + if (cell->elt->getTagId() == id) { + cell->elt->setName(string); + break; + } + } +} + +#ifdef DUMP +void +Dict::dictSetUnsaved() +{ + struct sCharCell *cell; + + for(cell = head; cell; cell = cell->next) + { + cell->elt->saved = 0; + } +} +#endif diff --git a/core/multimedia/opieplayer/libflash/character.h b/core/multimedia/opieplayer/libflash/character.h new file mode 100644 index 0000000..583cb17 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/character.h @@ -0,0 +1,90 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _CHARACTER_H_ +#define _CHARACTER_H_ + +enum ObjectType { + ShapeType, + TextType, + FontType, + SoundType, + BitmapType, + SpriteType, + ButtonType +}; + +class DisplayListEntry; + +// Character definition + +class Character { + long tagId; + ObjectType type; + char *name; + +public: + Character(ObjectType type, long tagId); + virtual ~Character(); + + virtual int execute(GraphicDevice *, Matrix *, Cxform *); // Display, play or whatever + virtual int isButton(void); // True if Character is a button + virtual int isSprite(void); + virtual ActionRecord *eventHandler(GraphicDevice *, FlashEvent *); + virtual void getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func); + virtual void reset(); // Reset internal state of object + virtual void getBoundingBox(Rect *bb, DisplayListEntry *de); +#ifdef DUMP + virtual void dump(BitStream *main); + + int saved; +#endif + + long getTagId(); // Return tagId + ObjectType getType(); + char *getTypeString(); + char *getName(); + void setName(char *); +}; + +struct sCharCell { + Character *elt; + struct sCharCell *next; +}; + +class Dict { + struct sCharCell *head; + struct sCharCell *currentCell; // Iteration variable for dictNextCharacter + +public: + Dict(); + ~Dict(); + + void addCharacter(Character *character); + void nameCharacter(long id, char *string); + Character *getCharacter(long id); + void dictRewind(); + Character *dictNextCharacter(); + +#ifdef DUMP + void dictSetUnsaved(); +#endif +}; + +#endif /* _CHARACTER_H_ */ diff --git a/core/multimedia/opieplayer/libflash/cxform.cc b/core/multimedia/opieplayer/libflash/cxform.cc new file mode 100644 index 0000000..b448f5d --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/cxform.cc @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id"; +#endif + +long +Cxform::getRed(long v) { + long val; + + val = (long)(ra*v+rb); + if (val > 255) val = 255; + else if (val < 0) val = 0; + return val; +} + +long +Cxform::getGreen(long v) { + long val; + + val = (long)(ga*v+gb); + if (val > 255) val = 255; + else if (val < 0) val = 0; + return val; +} + +long +Cxform::getBlue(long v) { + long val; + + val = (long)(ba*v+bb); + if (val > 255) val = 255; + else if (val < 0) val = 0; + return val; +} + +long +Cxform::getAlpha(long v) { + long val; + + val = (long)(aa*v+ab); + if (val > 255) val = 255; + else if (val < 0) val = 0; + return val; +} + +Color +Cxform::getColor(Color color) { + Color newColor; + + newColor.red = getRed(color.red); + newColor.green = getGreen(color.green); + newColor.blue = getBlue(color.blue); + newColor.alpha = getAlpha(color.alpha); + + return newColor; +} diff --git a/core/multimedia/opieplayer/libflash/cxform.h b/core/multimedia/opieplayer/libflash/cxform.h new file mode 100644 index 0000000..14f7189 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/cxform.h @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _CXFORM_H_ +#define _CXFORM_H_ + +struct Color { + unsigned char red,green,blue,alpha; + long pixel; +}; + +struct Cxform +{ + float aa; long ab; // a is multiply factor, b is addition factor + float ra; long rb; + float ga; long gb; + float ba; long bb; + + long getRed(long v); + long getGreen(long v); + long getBlue(long v); + long getAlpha(long v); + Color getColor(Color color); + +#ifdef DUMP + void dump(BitStream *bs, int alpha = 0); +#endif +}; + +#endif /* _CXFORM_H_ */ diff --git a/core/multimedia/opieplayer/libflash/displaylist.cc b/core/multimedia/opieplayer/libflash/displaylist.cc new file mode 100644 index 0000000..d71cfb7 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/displaylist.cc @@ -0,0 +1,708 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +void deleteButton(FlashMovie *movie, DisplayListEntry *e) +{ + /* save the focus */ + if (movie->mouse_active == 0 && e->renderState == stateOver) { + movie->lost_over = (Button *)e->character; + movie->cur_focus = NULL; + } + + if (e == movie->cur_focus) { + movie->cur_focus = NULL; + } +} + +void addButton(FlashMovie *movie, DisplayListEntry *e) +{ + if (movie->mouse_active == 0 && + movie->cur_focus == NULL && + movie->lost_over == (Button *)e->character) { + /* restore the lost focus */ + e->renderState = stateOver; + e->oldState = stateOver; + ((Button *)e->character)->updateButtonState(e); + movie->lost_over = NULL; + movie->cur_focus = e; + } +} + +DisplayList::DisplayList(FlashMovie *movie) +{ + list = NULL; + this->movie = movie; + bbox.reset(); + isSprite = 0; +} + +DisplayList::~DisplayList() +{ + clearList(); +} + +void +DisplayList::clearList() +{ + DisplayListEntry *del, *e; + + for(e = list; e;) + { + updateBoundingBox(e); + if (e->character->isButton()) { + deleteButton(movie,e); + } + del = e; + e = e->next; + delete del; + } + list = 0; +} + +DisplayListEntry * +DisplayList::getList() +{ + return list; +} + +static void bbox(Rect *rect, Matrix *m, long x1, long y1) +{ + long x,y; + + x = m->getX(x1,y1); + y = m->getY(x1,y1); + if (x < rect->xmin) rect->xmin = x; + if (x > rect->xmax) rect->xmax = x; + if (y < rect->ymin) rect->ymin = y; + if (y > rect->ymax) rect->ymax = y; +} + +// Update bb to include boundary, optional reset of bb +void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset) +{ + if (reset) { + bb->reset(); + } + + if (boundary->xmin != LONG_MAX) { + bbox(bb, matrix, boundary->xmin, boundary->ymin); + bbox(bb, matrix, boundary->xmax, boundary->ymin); + bbox(bb, matrix, boundary->xmin, boundary->ymax); + bbox(bb, matrix, boundary->xmax, boundary->ymax); + } +} + +void +DisplayList::placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix, Cxform *cxform, char *name) +{ + DisplayListEntry *n,*e,*prev; + + n = new DisplayListEntry; + if (n == NULL) return; + + n->depth = depth; + n->matrix = matrix; + n->cxform = cxform; + n->character = character; + n->instanceName = name; + n->owner = this; + +#if 0 + printf("Dl %lx: placeObject: depth=%d character=%d cxform=%p\n", + this, n->depth,n->character ? n->character->getTagId() : 0, cxform); +#endif + + if (character == 0 || matrix == 0 || cxform == 0) { + for (e = list; e; prev = e, e = e->next) { + if (e->depth == n->depth) { + if (character == 0) { + n->character = e->character; + } + if (matrix == 0) { + n->matrix = e->matrix; + } + if (cxform == 0) { + n->cxform = e->cxform; + } + break; + } + } + } + + if (n->character == 0) { + // Not found !!! Should not happen + // printf("PlaceObject cannot find character at depth %ld\n", n->depth); + delete n; + return; + } + + prev = 0; + for (e = list; e; prev = e, e = e->next) + { + if (e->depth == n->depth) { + if (e->character->isButton()) { + deleteButton(movie, e); + } + + // Do update, object has moved or been resized + updateBoundingBox(e); + + // Replace object + e->depth = n->depth; + e->matrix = n->matrix; + e->cxform = n->cxform; + e->character = n->character; + /* if it is a button, we must update its state */ + if (e->character->isButton()) { + movie->buttons_updated = 1; + addButton(movie, e); + } + + updateBoundingBox(e); + + delete n; + return; + } + if (e->depth > n->depth) break; + } + /* new object */ + + /* button instantiation */ + if (n->character->isButton()) { + n->renderState = stateUp; + n->oldState = stateUp; + ((Button *)n->character)->updateButtonState(n); + addButton(movie,n); + } + + updateBoundingBox(n); + + if (prev == 0) { + // Object comes at first place + n->next = list; + list = n; + } else { + // Insert object + n->next = prev->next; + prev->next = n; + } +} + + +Character * +DisplayList::removeObject(GraphicDevice *gd,Character *character, long depth) +{ + DisplayListEntry *e,*prev; + + // List should not be empty + if (list == 0) return 0; + +#if 0 + printf("removeObject: depth=%d character=%d\n", + depth,character ? character->getTagId() : 0); +#endif + + prev = 0; + for (e = list; e; prev = e, e = e->next) { + if (e->depth == depth) { + if (prev) { + prev->next = e->next; + } else { + list = e->next; + } + if (character == 0) { + character = e->character; + } + if (e->character->isButton()) { + deleteButton(movie, e); + } + if (e->character->isSprite()) { + ((Sprite*)e->character)->reset(); + } + + updateBoundingBox(e); + + delete e; + return character; + } + } + return 0; // Should not happen +} + +void +DisplayList::updateBoundingBox(DisplayListEntry *e) +{ + Rect rect; + + //rect.reset(); + e->character->getBoundingBox(&rect,e); + transformBoundingBox(&this->bbox, e->matrix, &rect, 0); +} + +int +DisplayList::updateSprites() +{ + Sprite *sprite; + DisplayListEntry *e; + int refresh = 0; + + for (e = this->list; e != NULL; e = e->next) { + if (e->character->isButton() && e->buttonCharacter) { + if (e->buttonCharacter->isSprite()) { + Matrix mat; + + sprite = (Sprite *)e->buttonCharacter; + refresh |= sprite->program->dl->updateSprites(); + refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform); + mat = (*e->matrix) * e->buttonMatrix; + transformBoundingBox(&this->bbox, &mat, + &(sprite->program->dl->bbox), + 0); + } + } + if (e->character->isSprite()) { + sprite = (Sprite *)e->character; + refresh |= sprite->program->dl->updateSprites(); + refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform); + transformBoundingBox(&this->bbox, e->matrix, + &(sprite->program->dl->bbox), + 0); + } + } + return refresh; +} + +/* Function can return either 0,1 or 2 + 0: Nothing match, continue + 1: Something matches, but continue searching + 2: Something matches, but stop searching +*/ + +static int exploreButtons1(Program *prg, void *opaque, + ExploreButtonFunc func) +{ + DisplayListEntry *e; + int ret, ret2 = 0; + + for(e=prg->dl->list; e != NULL; e = e->next) { + if (e->character == NULL) continue; + if (e->character->isButton()) { + ret = func(opaque,prg,e); + if (ret == 2) return ret; // Func asks to return at once !!! + if (ret) ret2 = 1; + } + if (e->character->isSprite()) { + ret = exploreButtons1(((Sprite *)e->character)->program, + opaque,func); + if (ret == 2) return ret; // Func asks to return at once !!! + if (ret) ret2 = 1; + } + } + return ret2; +} + +int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func) +{ + CInputScript *script; + int ret; + + script = movie->main; + while (script != NULL) { + if (script->program) { + ret = exploreButtons1(script->program, opaque, func); + if (ret) return ret; + } + script = script->next; + } + return 0; +} + +typedef struct { + long x,y; + int hit; + DisplayListEntry *bhit; +} HitTable; + +static void button_hit_func(void *id, long y, long start, long end) +{ + HitTable *h = (HitTable *) id; + if ( y == h->y && (h->x >= start && h->x < end) ) + h->hit = 1; +} + +typedef struct { + FlashMovie *movie; + DisplayListEntry *bhit; +} ButtonHit; + +static int button_hit(void *opaque, Program *prg, DisplayListEntry *e) +{ + ButtonHit *h = (ButtonHit *) opaque; + HitTable hit_table; + FlashMovie *movie = h->movie; + Rect bb,boundary; + Matrix mat; + ButtonState save; + + hit_table.x = movie->mouse_x; + hit_table.y = movie->mouse_y / FRAC; + hit_table.hit = 0; + + // Compute the bounding box in screen coordinates + save = e->renderState; + e->renderState = stateHitTest; + e->character->getBoundingBox(&boundary,e); + e->renderState = save; + mat = (*movie->gd->adjust) * e->renderMatrix; + transformBoundingBox(&bb, &mat, &boundary, 1); + // Check if mouse is within bb + if (movie->mouse_x < bb.xmin) return 0; + if (movie->mouse_x > bb.xmax) return 0; + if (movie->mouse_y < bb.ymin) return 0; + if (movie->mouse_y > bb.ymax) return 0; + + e->character->getRegion(movie->gd, &e->renderMatrix, + &hit_table, button_hit_func); + + if (hit_table.hit) { + h->bhit = e; + return 1; + } else { + return 0; + } +} + +static int button_reset(void *opaque, Program *prg, DisplayListEntry *e) +{ + if (e->renderState != stateUp) { + e->owner->updateBoundingBox(e); + e->oldState = e->renderState; + e->renderState = stateUp; + ((Button *)e->character)->updateButtonState(e); + e->owner->updateBoundingBox(e); + } + return 0; +} + +/* update the button states according to the current mouse state & return the list of actions */ +void +DisplayList::updateButtons(FlashMovie *movie) +{ + DisplayListEntry *bhit; + ButtonHit h; + + if (movie->mouse_active) { + + h.bhit = NULL; + h.movie = movie; + + exploreButtons(movie, &h, button_hit); + + bhit = h.bhit; + + /* set every button to not hit */ + exploreButtons(movie, NULL, button_reset); + + if (bhit) { + ButtonState state; + + if (movie->button_pressed) { + state = stateDown; + } else { + state = stateOver; + } + if (state != bhit->renderState) { + bhit->owner->updateBoundingBox(bhit); + bhit->renderState = state; + ((Button *)bhit->character)->updateButtonState(bhit); + bhit->owner->updateBoundingBox(bhit); + movie->cur_focus = bhit; + if (movie->cursorOnOff) + movie->cursorOnOff(1,movie->cursorOnOffClientData); + } + } else { + if (movie->cursorOnOff) + movie->cursorOnOff(0,movie->cursorOnOffClientData); + } + } +} + +typedef struct { + ActionRecord *action; // Action to do + Program *prg; // Context program +} ButtonAction; + +static int button_action(void *opaque, Program *prg, DisplayListEntry *e) +{ + ButtonAction *h = (ButtonAction *)opaque; + static ActionRecord actionRefresh; + static ActionRecord soundFx; + Button *b; + ActionRecord **paction; + int n; + + actionRefresh.action = ActionRefresh; + actionRefresh.next = 0; + + soundFx.action = ActionPlaySound; + soundFx.next = &actionRefresh; + + b = (Button *)e->character; + + if (e->oldState != e->renderState) { + + paction = &actionRefresh.next; + + if (b->conditionList) { + *paction = b->getActionFromTransition(e->renderState, e->oldState); + } else if (e->renderState == stateDown) { + /* if the button is pressed and + no condition list is defined*/ + *paction = b->actionRecords; + } + + switch(e->renderState) { + case stateUp: + n = 0; + break; + case stateOver: + n = 1; + break; + default: + /* case stateDown: */ + n = 2; + break; + } + + if (b->sound[n]) { + soundFx.sound = b->sound[n]; + h->action = &soundFx; + } else { + h->action = &actionRefresh; + } + + e->oldState = e->renderState; + + h->prg = prg; + return 2; + } + h->action = 0; // Nothing to do about this + return 0; +} + +int computeActions(FlashMovie *movie, Program **prg, ActionRecord **ar) +{ + ButtonAction h; + + h.action = NULL; + exploreButtons(movie, &h, button_action); + if (h.action) { + *prg = h.prg; + *ar = h.action; + return 1; + } + return 0; +} + +#define FOCUS_ZOOM 1.5 +/* in pixels */ +#define FOCUS_SIZE_MIN 50 +#define FOCUS_TRANSLATE 15 + +int +DisplayList::render(GraphicDevice *gd, Matrix *render_matrix, Cxform *cxform) +{ + DisplayListEntry *e,*cur_focus; + int sprite = 0; + long n = 0; + Cxform cxf,*cxf1; + Rect bb,boundary; + + cur_focus = NULL; + + /* + if (isSprite == 0) { + if (this->bbox.xmin == LONG_MAX) return 0; + gd->updateClippingRegion(&this->bbox, render_matrix); + gd->clearCanvas(); + } + */ + + for (e = list; e; e = e->next) + { +#if PRINT + printf("Character %3d @ %3d\n", e->character ? e->character->getTagId() : 0, e->depth); +#endif + if (e->character) { + Matrix mat; + + if (render_matrix) { + mat = *render_matrix; + } + + if (e->matrix) { + mat = mat * (*e->matrix); + } + + /* fast clipping */ + // If object boundaries are outside current clip region give up with rendering + e->character->getBoundingBox(&boundary,e); + if (boundary.xmin != LONG_MAX) { + Matrix tmat; + + tmat = (*gd->adjust) * mat; + transformBoundingBox(&bb, &tmat, &boundary, 1); + + bb.xmin = bb.xmin >> FRAC_BITS; + bb.ymin = bb.ymin >> FRAC_BITS; + bb.xmax = (bb.xmax + FRAC - 1) >> FRAC_BITS; + bb.ymax = (bb.ymax + FRAC - 1) >> FRAC_BITS; + + if (bb.xmin >= gd->clip_rect.xmax || + bb.xmax <= gd->clip_rect.xmin || + bb.ymin >= gd->clip_rect.ymax || + bb.ymax <= gd->clip_rect.ymin) { + continue; + } + } + + if (cxform == NULL) { + cxf1 = e->cxform; + } + else if (e->cxform == NULL) { + cxf1 = cxform; + } + else { + cxf1 = &cxf; + cxf.ra = cxform->ra * e->cxform->ra; + cxf.ga = cxform->ga * e->cxform->ga; + cxf.ba = cxform->ba * e->cxform->ba; + cxf.aa = cxform->aa * e->cxform->aa; + + cxf.rb = (long)(cxform->ra * e->cxform->rb + cxform->rb); + cxf.gb = (long)(cxform->ga * e->cxform->gb + cxform->gb); + cxf.bb = (long)(cxform->ba * e->cxform->bb + cxform->bb); + cxf.ab = (long)(cxform->aa * e->cxform->ab + cxform->ab); + } + + if (e->character->isButton()) { + Button *b = (Button *) e->character; + + e->renderMatrix = mat; + + if (e->renderState != stateUp && movie->mouse_active == 0) { + cur_focus = e; + ((Button *)e->character)->updateButtonState(e); + } + + if (b->execute(gd, &mat, cxf1, e->renderState)) { + sprite = 1; + } + } else { + if (e->character->execute(gd, &mat, cxf1)) { + sprite = 1; + } + } + + n++; + } + } + +#if 0 + { + /* display the bounding box (debug) */ + Matrix tmat; + long x1,x2,y1,y2; + Color white; + + white.red = 255; + white.green = white.blue = 0; + gd->setForegroundColor(white); + + if (render_matrix) { + tmat = (*gd->adjust) * (*render_matrix); + } else { + tmat = *gd->adjust; + } + x1 = bbox.xmin; + y1 = bbox.ymin; + x2 = bbox.xmax; + y2 = bbox.ymax; + gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),10*FRAC); + gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),10*FRAC); + gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),10*FRAC); + gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),10*FRAC); + bbox.print(); + } +#endif + + // Reset clipping zone + bbox.reset(); + + return sprite; +} + +void +DisplayList::getBoundary(Rect *bb) +{ + DisplayListEntry *e; + Rect boundary; + + bb->reset(); + for (e = list; e; e = e->next) + { + if (e->character) { + e->character->getBoundingBox(&boundary,e); + transformBoundingBox(bb, e->matrix, &boundary, 0); + } + } +} + +extern "C" { + +void dump_buttons(FlashHandle flashHandle) +{ +#if 0 + Rect rect; + DisplayListEntry *e; + FlashMovie *movie; + + movie = (FlashMovie *)flashHandle; + + for (e = movie->first_button; e; e = e->next_button) { + computeBBox(movie,&rect,e); + printf("button: id=%d pos=%d %d %d %d\n", + e->character->getTagId(), + rect.xmin, rect.ymin, rect.xmax, rect.ymax); + } +#endif +} + +} diff --git a/core/multimedia/opieplayer/libflash/displaylist.h b/core/multimedia/opieplayer/libflash/displaylist.h new file mode 100644 index 0000000..536f628 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/displaylist.h @@ -0,0 +1,80 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _DISPLAYLIST_H_ +#define _DISPLAYLIST_H_ + +class Character; +class Program; + +struct DisplayList; + +// Display List management +struct DisplayListEntry { + Character *character; + long depth; + Matrix *matrix; + Cxform *cxform; + char *instanceName; + + /* button state */ + ButtonState renderState; + ButtonState oldState; + Character *buttonCharacter; + Matrix buttonMatrix; + Matrix renderMatrix; /* last render matrix */ + + DisplayListEntry *next; + + DisplayList *owner; // Parent +}; + +struct DisplayList { + DisplayListEntry *list; + FlashMovie *movie; + Rect bbox; // Delta clipping region + int isSprite; +public: + DisplayList(FlashMovie *movie); + ~DisplayList(); + DisplayListEntry *getList(); + void clearList(); + void placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix = 0, Cxform *cxform = 0, char *name = 0); + Character *removeObject(GraphicDevice *gd, Character *character, long depth); + + int render(GraphicDevice *gd, Matrix *m = 0, Cxform *cxform = 0); + void updateBoundingBox(DisplayListEntry *); + void updateButtons (FlashMovie *); + void getBoundary(Rect *bb); // Returns boundary of current displayed objects + int updateSprites(); // Update sprites in the display list +}; + +typedef void (*DisplayListFunc)(DisplayListEntry *e, void *opaque); + +void updateButtons(FlashMovie *m); +int computeActions(FlashMovie *m, Program **prog, ActionRecord **ar); +void renderFocus(FlashMovie *movie); + +typedef int (*ExploreButtonFunc)(void *opaque, Program *prg, DisplayListEntry *e); +int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func); +void updateBoundingBox(DisplayListEntry *e); +void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset); +void updateButtonState(DisplayListEntry *e, ButtonState state); + +#endif /* _DISPLAYLIST_H_ */ diff --git a/core/multimedia/opieplayer/libflash/flash.cc b/core/multimedia/opieplayer/libflash/flash.cc new file mode 100644 index 0000000..75d351c --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/flash.cc @@ -0,0 +1,275 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" +#include "graphic16.h" +#include "graphic24.h" +#include "graphic32.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +// Interface with standard C +extern "C" { + +FlashHandle +FlashNew() +{ + FlashMovie *fh; + + fh = new FlashMovie; + + fh->main = new CInputScript; + + return (FlashHandle)fh; +} + +int +FlashParse(FlashHandle flashHandle, int level, char *data, long size) +{ + FlashMovie *fh; + CInputScript *script; + int status = FLASH_PARSE_ERROR; + + fh = (FlashMovie *)flashHandle; + + for(script = fh->main; script != NULL; script = script->next) { + if (script->level == level) { + status = script->ParseData(fh, data, size); + + if (status & FLASH_PARSE_START) { + fh->msPerFrame = 1000/fh->main->frameRate; + script->program->rewindMovie(); + } + break; + } + } + + return status; +} + +void +FlashGetInfo(FlashHandle flashHandle, struct FlashInfo *fi) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fi->version = fh->main->m_fileVersion; + fi->frameRate = fh->main->frameRate; + fi->frameCount = fh->main->frameCount; + fi->frameWidth = fh->main->frameRect.xmax - fh->main->frameRect.xmin; + fi->frameHeight = fh->main->frameRect.ymax - fh->main->frameRect.ymin; +} + +long FlashGraphicInit(FlashHandle flashHandle, FlashDisplay *fd) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + switch (fd->bpp) { + case 4: + fh->gd = new GraphicDevice32(fd); + break; + case 3: + fh->gd = new GraphicDevice24(fd); + break; + case 2: + fh->gd = new GraphicDevice16(fd); + break; + default: + fprintf(stderr, "Unsupported depth\n"); + } + + fh->gd->setMovieDimension(fh->main->frameRect.xmax - fh->main->frameRect.xmin, + fh->main->frameRect.ymax - fh->main->frameRect.ymin); + + return 1; // Ok +} + +void +FlashSoundInit(FlashHandle flashHandle, char *device) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->sm = new SoundMixer(device); +} + +void +FlashZoom(FlashHandle flashHandle, int zoom) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->gd->setMovieZoom(zoom); +} + +void +FlashOffset(FlashHandle flashHandle, int x, int y) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->gd->setMovieOffset(x,y); +} + +long +FlashExec(FlashHandle flashHandle, long flag, + FlashEvent *fe, struct timeval *wakeDate) +{ + FlashMovie *fh; + long wakeUp = 0; + + fh = (FlashMovie *)flashHandle; + + if (fh->main == NULL) return 0; // Not ready + if (fh->main->program == NULL) return 0; // Not ready + if (fh->main->program->nbFrames == 0) return 0; // Still not ready + if (fh->gd == 0) return 0; + + switch (flag & FLASH_CMD_MASK) { + case FLASH_STOP: + fh->main->program->pauseMovie(); + wakeUp = 0; + break; + case FLASH_CONT: + fh->main->program->continueMovie(); + wakeUp = FLASH_STATUS_WAKEUP; + break; + case FLASH_REWIND: + fh->main->program->rewindMovie(); + wakeUp = 0; + break; + case FLASH_STEP: + fh->main->program->nextStepMovie(); + wakeUp = 0; + break; + } + + if (flag & FLASH_WAKEUP) { + // Compute next wakeup time + gettimeofday(wakeDate,0); + wakeDate->tv_usec += fh->msPerFrame*1000; + if (wakeDate->tv_usec > 1000000) { + wakeDate->tv_usec -= 1000000; + wakeDate->tv_sec++; + } + + // Play frame + wakeUp = fh->processMovie(fh->gd, fh->sm); + } + + if (checkFlashTimer(&fh->scheduledTime)) { + if (fh->handleEvent(fh->gd, fh->sm, &fh->scheduledEvent)) { + wakeUp = 1; + } + + setFlashTimer(&fh->scheduledTime, -1); + } + + if (flag & FLASH_EVENT) { + wakeUp = fh->handleEvent(fh->gd, fh->sm, fe); + if (wakeUp) { + /* Wake up at once, except for mouse move (40 ms after) */ + gettimeofday(wakeDate,0); + if (fe->type == FeMouseMove) { + wakeDate->tv_usec += 40*1000; + if (wakeDate->tv_usec > 1000000) { + wakeDate->tv_usec -= 1000000; + wakeDate->tv_sec++; + } + } + } + } + + return wakeUp || (fh->scheduledTime.tv_sec != -1); +} + +void FlashSetGetSwfMethod(FlashHandle flashHandle, void (*getSwf)(char *url, int level, void *clientData), void *clientData) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->getSwf = getSwf; + fh->getSwfClientData = clientData; +} + + +void +FlashSetCursorOnOffMethod(FlashHandle flashHandle, void (*cursorOnOff)(int , void *), void *clientData) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->cursorOnOff = cursorOnOff; + fh->cursorOnOffClientData = clientData; +} + +void +FlashSetGetUrlMethod(FlashHandle flashHandle, void (*getUrl)(char *, char *, void *), void *clientData) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->getUrl = getUrl; + fh->getUrlClientData = clientData; +} + +void +FlashClose(FlashHandle flashHandle) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + delete fh; +} + +void +FlashSettings(FlashHandle flashHandle, long settings) +{ + FlashMovie *fh; + + fh = (FlashMovie *)flashHandle; + + fh->main->program->modifySettings( settings ); +} + +int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb; + +void flash_dump(void) +{ + printf("flash: shape_size=%d (nb=%d)\n",shape_size,shape_nb); + printf("flash: shaperecord_size=%d (nb=%d)\n",shaperecord_size,shaperecord_nb); + printf("flash: style_size=%d (nb=%d)\n",style_size,style_nb); +} + +}; /* end of extern C */ diff --git a/core/multimedia/opieplayer/libflash/flash.h b/core/multimedia/opieplayer/libflash/flash.h new file mode 100644 index 0000000..9330713 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/flash.h @@ -0,0 +1,129 @@ +/*/////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +///////////////////////////////////////////////////////////// */ +#ifndef _FLASH_H_ +#define _FLASH_H_ + +#define PLUGIN_NAME "Shockwave Flash" +#define FLASH_VERSION_STRING "Version 0.4.10" + +/* Flags to pass to FlashExec */ +#define FLASH_WAKEUP 0x01 +#define FLASH_EVENT 0x02 +#define FLASH_CMD 0x04 + +/* Mask to extract commands */ +#define FLASH_CMD_MASK 0xf0 +/* Commands */ +#define FLASH_STOP 0x10 /* Pause the movie */ +#define FLASH_CONT 0x20 /* Continue the movie after pause */ +#define FLASH_REWIND 0x30 /* Rewind the movie and pause */ +#define FLASH_STEP 0x40 /* Frame by frame operation */ + +/* return codes of FlashExec */ +#define FLASH_STATUS_WAKEUP 0x01 /* FlashExec must be called again after a given time */ + +struct FlashInfo { + long frameRate; + long frameCount; + long frameWidth; + long frameHeight; + long version; +}; + +/* Player settings */ +#define PLAYER_LOOP (1<<0) +#define PLAYER_QUALITY (1<<1) +#define PLAYER_MENU (1<<2) + +/* Parser status */ +#define FLASH_PARSE_ERROR 0 +#define FLASH_PARSE_START 1 +#define FLASH_PARSE_NEED_DATA 2 +#define FLASH_PARSE_EOM 4 +#define FLASH_PARSE_WAKEUP 8 +#define FLASH_PARSE_OOM 16 /* Out Of Memory */ + +typedef void *FlashHandle; + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +enum FlashEventType { + FeNone, + FeMouseMove, + FeButtonPress, + FeButtonRelease, + FeRefresh, + FeKeyPress, + /* internal events */ + FeKeyRelease, +}; + +enum FlashKey { + FeKeyUp = 1, + FeKeyDown, + FeKeyLeft, + FeKeyRight, + FeKeyEnter, + FeKeyNext +}; + + + +typedef struct FlashEvent { + enum FlashEventType type; + int x,y; /* Mouse coordinates, + relative to upper-left window corner */ + enum FlashKey key; +} FlashEvent; + +typedef struct FlashDisplay { + void *pixels; + int bpl; /* bytes per line */ + int width; + int height; + int depth; + int bpp; + int flash_refresh; + /* Clipping region */ + int clip_x, clip_y; + int clip_width, clip_height; +} FlashDisplay; + +extern FlashHandle FlashNew(); +extern void FlashGetInfo(FlashHandle fh, struct FlashInfo *fi); +extern long FlashGraphicInit(FlashHandle fh, FlashDisplay *fd); +extern void FlashSoundInit(FlashHandle fh, char *device); +extern int FlashParse(FlashHandle fh, int level, char *data, long size); +extern long FlashExec(FlashHandle fh, long flag, FlashEvent *fe, struct timeval *wakeDate); +extern void FlashClose(FlashHandle fh); +extern void FlashSetGetUrlMethod(FlashHandle flashHandle, void (*getUrl)(char *, char *, void *), void *); +extern void FlashSetGetSwfMethod(FlashHandle flashHandle, void (*getSwf)(char *url, int level, void *clientData), void *clientData); +extern void FlashSetCursorOnOffMethod(FlashHandle flashHandle, void (*cursorOnOff)(int , void *), void *clientData); +extern void FlashZoom(FlashHandle fh, int zoom); +extern void FlashOffset(FlashHandle fh, int x, int y); +extern void FlashSettings(FlashHandle fh, long settings); + +#if defined(__cplusplus) || defined(c_plusplus) +}; +#endif + +#endif /* _FLASH_H_ */ diff --git a/core/multimedia/opieplayer/libflash/font.cc b/core/multimedia/opieplayer/libflash/font.cc new file mode 100644 index 0000000..d937276 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/font.cc @@ -0,0 +1,105 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +SwfFont::SwfFont(long id) : Character(FontType, id) +{ + glyphs = 0; + nbGlyphs = 0; + name = NULL; + setFontName("Unknown"); + flags = (FontFlags)0; + lookUpTable = 0; +} + +SwfFont::~SwfFont() +{ + if (lookUpTable) { + delete lookUpTable; + } + delete name; + delete [] glyphs; +} + +void +SwfFont::setFontFlags(FontFlags f) +{ + flags = f; +} + +char * +SwfFont::getName() +{ + return name; +} + +FontFlags +SwfFont::getFlags() +{ + return flags; +} + +long +SwfFont::getNbGlyphs() +{ + return nbGlyphs; +} + +Shape * +SwfFont::getGlyph(long index) +{ + if (index >= nbGlyphs) return 0; + return &glyphs[index]; +} + +long +SwfFont::getGlyphCode(long index) +{ + if (lookUpTable == 0 || index >= nbGlyphs) return 0; + return lookUpTable[index]; +} + +void +SwfFont::setFontName(char *str) +{ + delete name; + name = new char[strlen(str)+1]; + strcpy(name,str); +} + +void +SwfFont::setFontLookUpTable(long *lut) +{ + lookUpTable = lut; +} + +void +SwfFont::setFontShapeTable(Shape *shapes, long n) +{ + glyphs = shapes; + nbGlyphs = n; +} diff --git a/core/multimedia/opieplayer/libflash/font.h b/core/multimedia/opieplayer/libflash/font.h new file mode 100644 index 0000000..bc151ca --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/font.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _SWFFONT_H_ +#define _SWFFONT_H_ + +class SwfFont : public Character { + Shape *glyphs; // Array + long nbGlyphs; + char *name; + FontFlags flags; + long *lookUpTable; // Array + + // Font2 + long ascent; + long descent; + long leading; + +public: + SwfFont(long id); + ~SwfFont(); + + void setFontShapeTable(Shape *shapes, long n); + void setFontName(char *str); + void setFontLookUpTable(long *lut); + void setFontFlags(FontFlags f); + long getGlyphCode(long index); + long getNbGlyphs(); + Shape *getGlyph(long index); + + char *getName(); + FontFlags getFlags(); + +#ifdef DUMP + void dump(BitStream *bs); + void dumpFontInfo(BitStream *bs); +#endif +}; + +#endif /* _SWFFONT_H_ */ diff --git a/core/multimedia/opieplayer/libflash/graphic.cc b/core/multimedia/opieplayer/libflash/graphic.cc new file mode 100644 index 0000000..f65011e --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic.cc @@ -0,0 +1,632 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +// Public + +GraphicDevice::GraphicDevice(FlashDisplay *fd) +{ + flashDisplay = fd; + + bgInitialized = 0; + + // Reset flash refresh flag + flashDisplay->flash_refresh = 0; + + /* 16 bits, RGB565 */ + redMask = 0xF800; + greenMask = 0x07E0; + blueMask = 0x001F; + + /* should be the actual window size */ + targetWidth = fd->width; + targetHeight = fd->height; + bpl = fd->bpl; + +#if PRINT + printf("Target Width = %d\n", targetWidth); + printf("Target Height = %d\n", targetHeight); +#endif + + zoom = FRAC; + movieWidth = targetWidth; + movieHeight = targetHeight; + + viewPort.xmin = 0; + viewPort.xmax = targetWidth-1; + viewPort.ymin = 0; + viewPort.ymax = targetHeight-1; + + canvasBuffer = (unsigned char *) fd->pixels; + + adjust = new Matrix; + foregroundColor.red = 0; + foregroundColor.green = 0; + foregroundColor.blue = 0; + foregroundColor.alpha = ALPHA_OPAQUE; + + backgroundColor.red = 0; + backgroundColor.green = 0; + backgroundColor.blue = 0; + backgroundColor.alpha = ALPHA_OPAQUE; + + showMore = 0; + + setClipping(0); // Reset + setClipping(1); + + /* polygon rasterizer : handle memory errors ! */ + + height = targetHeight; + segs = (Segment **)malloc(height * sizeof(Segment *)); + memset(segs, 0, height * sizeof(Segment *)); + ymin = height; + ymax = -1; + + seg_pool = (Segment *)malloc(NB_SEGMENT_MAX * sizeof(Segment)); + seg_pool_cur = seg_pool; +} + +GraphicDevice::~GraphicDevice() +{ + free(segs); + free(seg_pool); + + if (adjust) { + delete adjust; + } +} + +Color * +GraphicDevice::getColormap(Color *old, long n, Cxform *cxform) +{ + Color *newCmp; + + newCmp = new Color[n]; + if (newCmp == NULL) return NULL; + + if (cxform) { + for(long i = 0; i < n; i++) + { + newCmp[i] = cxform->getColor(old[i]); + newCmp[i].pixel = allocColor(newCmp[i]); + } + } else { + for(long i = 0; i < n; i++) + { + newCmp[i] = old[i]; + newCmp[i].pixel = allocColor(old[i]); + } + } + + return newCmp; +} + +long +GraphicDevice::getHeight() +{ + return targetHeight; +} + +long +GraphicDevice::getWidth() +{ + return targetWidth; +} + +Color +GraphicDevice::getForegroundColor() +{ + return foregroundColor; +} + +void +GraphicDevice::setForegroundColor(Color color) +{ + foregroundColor = color; +} + +Color +GraphicDevice::getBackgroundColor() +{ + return backgroundColor; +} + +int +GraphicDevice::setBackgroundColor(Color color) +{ + if (bgInitialized == 0) { + backgroundColor = color; + clearCanvas(); + bgInitialized = 1; + return 1; + } + return 0; +} + +void +GraphicDevice::setMovieDimension(long width, long height) +{ + float xAdjust, yAdjust; + + movieWidth = width; + movieHeight = height; + + xAdjust = (float)targetWidth*zoom/(float)width; + yAdjust = (float)targetHeight*zoom/(float)height; + + if (xAdjust < yAdjust) { + adjust->a = xAdjust; + adjust->d = xAdjust; + adjust->ty = ((targetHeight*zoom) - (long)(height * xAdjust))/2; + viewPort.ymin = adjust->ty/zoom; + viewPort.ymax = targetHeight-viewPort.ymin-1; + } else { + adjust->a = yAdjust; + adjust->d = yAdjust; + adjust->tx = ((targetWidth*zoom) - (long)(width * yAdjust))/2; + viewPort.xmin = adjust->tx/zoom; + viewPort.xmax = targetWidth-viewPort.xmin-1; + } + + if (viewPort.xmin < 0) viewPort.xmin = 0; + if (viewPort.ymin < 0) viewPort.ymin = 0; + if (viewPort.xmax >= targetWidth) viewPort.xmax = targetWidth-1; + if (viewPort.ymax >= targetHeight) viewPort.ymax = targetHeight-1; +} + +void +GraphicDevice::setMovieZoom(int z) +{ + z *= FRAC; + if (z <= 0 || z > 100) return; + zoom = z; + setMovieDimension(movieWidth,movieHeight); +} + +void +GraphicDevice::setMovieOffset(long x, long y) +{ + adjust->tx = -zoom*x; + adjust->ty = -zoom*y; +} + +long +GraphicDevice::clip(long &y, long &start, long &end) +{ + long xmin,xend; + + if (y < clip_rect.ymin || + y >= clip_rect.ymax) return 1; + if (end <= start) + return 1; + xmin = clip_rect.xmin * FRAC; + xend = clip_rect.xmax * FRAC; + + if (end <= xmin || start >= xend) return 1; + + if (start < xmin) start = xmin; + if (end > xend) end = xend; + + return 0; +} + +void +GraphicDevice::drawBox(long x1, long y1, long x2, long y2) +{ + int i; + + for(i=0;i= NB_SEGMENT_MAX ) + return NULL; + seg = seg_pool_cur++; + + return seg; +} + +/* add a segment to the current path */ +void +GraphicDevice::addSegment(long x1, long y1, long x2, long y2, + FillStyleDef *f0, + FillStyleDef *f1, + int aa) +{ + Segment *seg,**segs; + long dX, X, Y, ymin, ymax, tmp; + FillStyleDef *ff; + + if ( y1 == y2 ) { + return; + } + + if (y1 < y2) { + ymin = y1; + ymax = y2; + ff = f0; + f0 = f1; + f1 = ff; + } else { + ymin = y2; + ymax = y1; + tmp = x1; + x1 = x2; + x2 = tmp; + } + + if (ymax>>FRAC_BITS < clip_rect.ymin) { + return; + } + if (ymin>>FRAC_BITS > clip_rect.ymax) { + return; + } + + X = x1 << SEGFRAC; + dX = ((x2 - x1)< ymax) { + //printf("Elimine @ y = %d ymin = %d, ymax = %d\n", Y, ymin, seg->ymax); + return; + } + X += dX * (Y-ymin); + + Y >>= FRAC_BITS; + if (Y >= clip_rect.ymax) { + return; + } + + seg = allocSeg(); + if (seg == NULL) { + return; + } + + seg->next = 0; + seg->nextValid = 0; + seg->aa = aa; + seg->ymax = ymax; + seg->x1 = x1; + seg->x2 = x2; + seg->X = X; + seg->dX = dX; + seg->fs[0] = f0; + seg->fs[1] = f1; + + if (Y < this->ymin) this->ymin = Y; + ymax = (seg->ymax + FRAC - 1) >> FRAC_BITS; + if (ymax >= this->height) ymax = this->height-1; + if (ymax > this->ymax) this->ymax = ymax; + + segs = this->segs; + + if (segs[Y] == 0) { + segs[Y] = seg; + } else { + Segment *s,*prev; + + prev = 0; + for(s = segs[Y]; s; prev = s, s = s->next) { + if (s->X > seg->X) { + if (prev) { + prev->next = seg; + seg->next = s; + } else { + seg->next = segs[Y]; + segs[Y] = seg; + } + break; + } + } + if (s == 0) { + prev->next = seg; + seg->next = s; + } + } +} + +inline Segment * +GraphicDevice::progressSegments(Segment * curSegs, long y) +{ + Segment *seg,*prev; + + // Update current segments + seg = curSegs; + prev = 0; + while(seg) + { + if ((y*FRAC) > seg->ymax) { + // Remove this segment, no more valid + if (prev) { + prev->nextValid = seg->nextValid; + } else { + curSegs = seg->nextValid; + } + seg = seg->nextValid; + } else { + seg->X += seg->dX * FRAC; + prev = seg; + seg = seg->nextValid; + } + } + return curSegs; +} + +inline Segment * +GraphicDevice::newSegments(Segment *curSegs, Segment *newSegs) +{ + Segment *s,*seg,*prev; + + s = curSegs; + prev = 0; + + // Check for new segments + for (seg = newSegs; seg; seg=seg->next) + { + // Place it at the correct position according to X + if (curSegs == 0) { + curSegs = seg; + seg->nextValid = 0; + } else { + for(; s; prev = s, s = s->nextValid) + { + if ( s->X > seg->X || + ( (s->X == seg->X) && + ( (seg->x1 == s->x1 && seg->dX < s->dX) || + (seg->x2 == s->x2 && seg->dX > s->dX) + ))) { + // Insert before s + if (prev) { + seg->nextValid = s; + prev->nextValid = seg; + } else { + seg->nextValid = curSegs; + curSegs = seg; + } + break; + } + } + // Append at the end + if (s == 0) { + prev->nextValid = seg; + seg->nextValid = 0; + } + } + + s = seg; + } + + return curSegs; +} + +#if 0 +static void +printSeg(Segment *seg) +{ + /* + printf("Seg %08x : X = %5d, Ft = %d, Cl = %2x/%2x/%2x, Cr = %2x/%2x/%2x, x1=%5d, x2=%5d, ymin=%5d, ymax=%5d\n", seg, + seg->X>>SEGFRAC, + seg->right ? seg->right->type: -1, + seg->left ? seg->left->color.red : -1, + seg->left ? seg->left->color.green : -1, + seg->left ? seg->left->color.blue : -1, + seg->right ? seg->right->color.red : -1, + seg->right ? seg->right->color.green : -1, + seg->right ? seg->right->color.blue : -1, + seg->x1, seg->x2, seg->ymin, seg->ymax); + */ +} +#endif + +inline void +GraphicDevice::renderScanLine(long y, Segment *curSegs) +{ + Segment *seg; + long width; + int fi = 1; + FillStyleDef *f; + + width = targetWidth * FRAC; + + if (curSegs && curSegs->fs[0] && curSegs->fs[1] == 0) { + fi = 0; + } + for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid) + { + if (seg->nextValid->X <0) continue; + if ((seg->X>>SEGFRAC) > width) break; + f = seg->fs[fi]; + if (f) { + switch (f->type) { + case f_Solid: + if (seg->aa) { + fillLineAA(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + } else { + fillLine(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + } + break; + case f_TiledBitmap: + case f_clippedBitmap: + fillLineBitmap(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + break; + case f_LinearGradient: + fillLineLG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + break; + case f_RadialGradient: + fillLineRG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + break; + case f_None: + break; + } + } + } +} + +/* draw the current path */ +void +GraphicDevice::drawPolygon(void) +{ + long y; + Segment *curSegs,*seg; + + // no segments ? + if (this->ymax == -1) + return; + + // Foreach scanline + curSegs = 0; + for(y=this->ymin; y <= this->ymax; y++) { + + // Make X values progess and remove unuseful segments + curSegs = progressSegments(curSegs, y); + + // Add the new segment starting at the y position. + curSegs = newSegments(curSegs, this->segs[y]); + + // Render the scanline + if (this->scan_line_func == NULL) { + renderScanLine(y, curSegs); + } else { + for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid) { + if (seg->nextValid->X >= seg->X) { + scan_line_func(this->scan_line_func_id, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC); + } + } + } + } + + /* free the segments */ + memset(this->segs + this->ymin, 0, + (this->ymax - this->ymin + 1) * sizeof(Segment *)); + + this->ymax = -1; + this->ymin = this->height; + + this->seg_pool_cur = this->seg_pool; +} + +void +GraphicDevice::updateClippingRegion(Rect *rect) +{ + if (!clipping) return; + + transformBoundingBox(&clip_rect, adjust, rect, 1); + clip_rect.xmin >>= FRAC_BITS; + clip_rect.xmax >>= FRAC_BITS; + clip_rect.ymin >>= FRAC_BITS; + clip_rect.ymax >>= FRAC_BITS; + + clip_rect.xmin-=2; + clip_rect.ymin-=2; + clip_rect.xmax+=2; + clip_rect.ymax+=2; + + if (clip_rect.xmin < viewPort.xmin) clip_rect.xmin = viewPort.xmin; + if (clip_rect.xmax < viewPort.xmin) clip_rect.xmax = viewPort.xmin; + if (clip_rect.ymin < viewPort.ymin) clip_rect.ymin = viewPort.ymin; + if (clip_rect.ymax < viewPort.ymin) clip_rect.ymax = viewPort.ymin; + + if (clip_rect.xmax > viewPort.xmax) clip_rect.xmax = viewPort.xmax; + if (clip_rect.ymax > viewPort.ymax) clip_rect.ymax = viewPort.ymax; + if (clip_rect.xmin > viewPort.xmax) clip_rect.xmin = viewPort.xmax; + if (clip_rect.ymin > viewPort.ymax) clip_rect.ymin = viewPort.ymax; +} + +void +GraphicDevice::setClipping(int value) +{ + clipping = value; + if (clipping == 0) { + // Reset region + clip_rect.xmin = viewPort.xmin; + clip_rect.xmax = viewPort.xmax; + clip_rect.ymin = viewPort.ymin; + clip_rect.ymax = viewPort.ymax; + } +} + +// Virtual +void +GraphicDevice::clearCanvas() +{ +} + +long +GraphicDevice::allocColor(Color color) +{ + return 0; +} + +void +GraphicDevice::fillLineBitmap(FillStyleDef *f, long y, long start, long end) +{ +} + +void +GraphicDevice::fillLineLG(Gradient *grad, long y, long start, long end) +{ +} + +void +GraphicDevice::fillLineRG(Gradient *grad, long y, long start, long end) +{ +} + +void +GraphicDevice::fillLine(FillStyleDef *f, long y, long start, long end) +{ +} + +void +GraphicDevice::fillLineAA(FillStyleDef *f, long y, long start, long end) +{ +} + +void +GraphicDevice::drawLine(long x1, long y1, long x2, long y2, long width) +{ +} diff --git a/core/multimedia/opieplayer/libflash/graphic.h b/core/multimedia/opieplayer/libflash/graphic.h new file mode 100644 index 0000000..63ebd99 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic.h @@ -0,0 +1,174 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _GRAPHIC_H_ +#define _GRAPHIC_H_ + +#define ALPHA_OPAQUE 255 + +enum FillType { + f_Solid = 0x00, + f_LinearGradient = 0x10, + f_RadialGradient = 0x12, + f_TiledBitmap = 0x40, + f_clippedBitmap = 0x41, + f_None = 0x80 +}; + +struct Gradient { + int nbGradients; + unsigned char ratio[8]; + Color color[8]; + // For rendering + Color *ramp; + Matrix imat; + int has_alpha; +}; + + +struct FillStyleDef { + FillType type; // See enum FillType + + // Solid + Color color; + + // Gradient + Gradient gradient; + + // Bitmap + Bitmap *bitmap; + Matrix bitmap_matrix; + Color *cmap; + unsigned char *alpha_table; + + // Gradient or Bitmap + Matrix matrix; + + FillStyleDef() { + style_size += sizeof(FillStyleDef); + style_nb++; + } +}; + +struct Segment { + long x1,x2; + long ymax; + FillStyleDef *fs[2]; // 0 is left 1 is right + int aa; + long dX; + long X; + + struct Segment *next; + struct Segment *nextValid; +}; + +/* fractional bits (we don't use twips here... too expensive) */ +#define FRAC_BITS 5 +#define FRAC (1 << FRAC_BITS) +#define NB_SEGMENT_MAX (2048*4) +#define SEGFRAC 8 + +class GraphicDevice { + int targetWidth; + int targetHeight; + Rect viewPort; + int movieWidth; + int movieHeight; + int zoom; + unsigned long redMask; + unsigned long greenMask; + unsigned long blueMask; + int clipping; + +public: + FlashDisplay *flashDisplay; + int bgInitialized; + Color backgroundColor; + Color foregroundColor; + +public: + void *scan_line_func_id; + ScanLineFunc scan_line_func; + Rect clip_rect; + +private: + Segment **segs; + int ymin,ymax; + int height; + Segment *seg_pool; + Segment *seg_pool_cur; + + Segment * allocSeg(); + Segment * progressSegments(Segment * curSegs, long y); + Segment * newSegments(Segment *curSegs, Segment *newSegs); + void renderScanLine(long y, Segment *curSegs); + +protected: + long clip(long &y, long &start, long &end); + +public: + Matrix *adjust; // Matrix to fit window (shrink or expand) + + long showMore; // Used for debugging + + // For Direct Graphics + unsigned char *canvasBuffer; // A pointer to canvas'memory + long bpl; // Bytes per line + long bpp; // Bytes per pixel + long pad; // Scanline pad in byte + + GraphicDevice(FlashDisplay *fd); + virtual ~GraphicDevice(); + + int setBackgroundColor(Color); + void setForegroundColor(Color); + Color getBackgroundColor(); + Color getForegroundColor(); + void setMovieDimension(long width, long height); + void setMovieZoom(int zoom); + void setMovieOffset(long x, long y); + long getWidth(); + long getHeight(); + Color *getColormap(Color *old, long n, Cxform *cxform); + + void drawBox(long x1, long y1, long x2, long y2); + + void addSegment(long x1, long y1, long x2, long y2, + FillStyleDef *f0, + FillStyleDef *f1, + int aa); + + void drawPolygon(void); + + void updateClippingRegion(Rect *); + void setClipping(int); + + // Virtual functions + virtual void clearCanvas(); + virtual long allocColor(Color color); + virtual void fillLineBitmap(FillStyleDef *f, long y, long start, long end); + virtual void fillLineLG(Gradient *grad, long y, long start, long end); + virtual void fillLineRG(Gradient *grad, long y, long start, long end); + virtual void fillLine(FillStyleDef *f, long y, long start, long end); + virtual void fillLineAA(FillStyleDef *f, long y, long start, long end); + virtual void drawLine(long x1, long y1, long x2, long y2, long width); + +}; + +#endif /* _GRAPHIC_H_ */ diff --git a/core/multimedia/opieplayer/libflash/graphic16.cc b/core/multimedia/opieplayer/libflash/graphic16.cc new file mode 100644 index 0000000..24d0c20 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic16.cc @@ -0,0 +1,658 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#include "graphic16.h" + +extern unsigned char SQRT[]; + +#define FULL_AA + +#define PRINT 0 + +typedef unsigned short TYPE; + +GraphicDevice16::GraphicDevice16(FlashDisplay *fd) : GraphicDevice(fd) +{ +} + +long +GraphicDevice16::allocColor(Color color) +{ + return (color.red >> 3)<<11 | (color.green>>2)<<5 | (color.blue>>3); +} + +void +GraphicDevice16::clearCanvas() +{ + TYPE pixel; + TYPE *point,*p; + long h, w,n; + + if (!bgInitialized) return; + + pixel = allocColor(backgroundColor); + + point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin; + w = clip_rect.xmax - clip_rect.xmin; + h = clip_rect.ymax - clip_rect.ymin; + + while (h--) { + p = point; + n = w; + while (n--) { + *p++ = pixel; + } + + point = (TYPE *)((char *)point + bpl); + } + + flashDisplay->flash_refresh = 1; + flashDisplay->clip_x = clip_rect.xmin; + flashDisplay->clip_y = clip_rect.ymin; + flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin; + flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin; +} + +#define RED_MASK 0xF800 +#define GREEN_MASK 0x07E0 +#define BLUE_MASK 0x001F + +/* alpha = 0 : select c1, alpha = 255 select c2 */ +static inline unsigned long +mix_alpha(unsigned long c1, + unsigned long c2, int alpha) +{ + long r1,r2,r; + long g1,g2,g; + long b1,b2,b; + + r1 = c1 & RED_MASK; + r2 = c2 & RED_MASK; + r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK; + + g1 = c1 & GREEN_MASK; + g2 = c2 & GREEN_MASK; + g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK; + + b1 = c1 & BLUE_MASK; + b2 = c2 & BLUE_MASK; + b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK; + + return (r|g|b); +} + +void +GraphicDevice16::fillLineAA(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line; + TYPE *point,pixel; + unsigned int alpha, start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + line = (TYPE *)(canvasBuffer + bpl*y); + + alpha = f->color.alpha; + pixel = f->color.pixel; + + if (alpha == ALPHA_OPAQUE) { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start]; + + if (start == end) { + *point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255); + } else { + n = end-start; + if (start_alpha < 255) { + *point = mix_alpha(*point, pixel, start_alpha); + point++; + n--; + } + while (n > 0) { + *point = pixel; + point++; + n--; + } + if (end_alpha > 0) { + *point = mix_alpha(*point, pixel, end_alpha); + } + } + } else { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start]; + + if (start == end) { + *point = mix_alpha(*point, pixel, + ((start_alpha + end_alpha - 255) * alpha) >> 8); + } else { + n = end-start; + if (start_alpha < 255) { + *point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8); + point++; + n--; + } + while (n > 0) { + *point = mix_alpha(*point, pixel, alpha); + point++; + n--; + } + if (end_alpha > 0) { + *point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8); + } + } + } +} + +void +GraphicDevice16::fillLine(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line,*point; + TYPE pixel; + unsigned int alpha; + + if (clip(y,start,end)) return; + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + n = end-start; + pixel = f->color.pixel; + alpha = f->color.alpha; + if (alpha == ALPHA_OPAQUE) { + while (n--) { + *point = pixel; + point++; + } + } else { + while (n--) { + *point = mix_alpha(*point, pixel, alpha); + point++; + } + } +} + +void +GraphicDevice16::fillLineBitmap(FillStyleDef *f, long y, long start, long end) +{ + int n; + long x1,y1,dx,dy; + Matrix *m = &f->bitmap_matrix; + Bitmap *b = f->bitmap; + unsigned char *pixels; + TYPE *p; + Color *cmap; + long pixbpl; + TYPE pixel; + int offset; + unsigned char *alpha_table; + + /* safety test) */ + if (!b) return; + + if (clip(y,start,end)) return; + + start /= FRAC; + end /= FRAC; + n = end - start; + p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * 2); + + /* the coordinates in the image are normalized to 16 bits */ + x1 = (long) (m->a * start + m->b * y + m->tx); + y1 = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + pixels = b->pixels; + pixbpl = b->bpl; + cmap = f->cmap; + + if (b->alpha_buf == NULL) { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel; + *p = pixel; + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } else if (f->alpha_table) { + alpha_table = f->alpha_table; + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + pixel = cmap[pixels[offset]].pixel; + *p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]); + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } else { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + pixel = cmap[pixels[offset]].pixel; + *p = mix_alpha(*p, pixel, b->alpha_buf[offset]); + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } +} + +void +GraphicDevice16::fillLineLG(Gradient *grad, long y, long start, long end) +{ + long dr,r,v,r2; + register long n; + TYPE *line; + TYPE *point; + Color *cp,*ramp; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + r = (long) (m->a * start + m->b * y + m->tx); + dr = (long) (m->a); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + + r2 = r + n * dr; + if ( ((r | r2) & ~255) == 0 ) { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha); + point++; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + *point = (TYPE)ramp[v].pixel; + point++; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + cp = &ramp[v]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + r += dr; + } + } + } else { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha); + point++; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = (TYPE)ramp[v].pixel; + point++; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + cp = &ramp[v]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + r += dr; + } + } + } +} + +void +GraphicDevice16::fillLineRG(Gradient *grad, long y, long start, long end) +{ + long X,dx,r,Y,dy; + long dist2; + register long n; + Color *cp,*ramp; + TYPE *line; + TYPE *point; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + X = (long) (m->a * start + m->b * y + m->tx); + Y = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start == end) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r = SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255); + } else { + if (start_alpha < 255) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r = SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha); + point++; + X += dx; + Y += dy; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + *point = (TYPE)ramp[r].pixel; + point++; + X += dx; + Y += dy; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha); + } + } +#endif /* FULL_AA */ + + } else { + while (n--) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + cp = &ramp[r]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + X += dx; + Y += dy; + } + } +} + +void +GraphicDevice16::drawLine(long x1, long y1, long x2, long y2, long width) +{ + int n,adr,dx,dy,sx,color; + register int a; + register TYPE *pp; + int alpha; + + x1 = (x1) >> FRAC_BITS; + y1 = (y1) >> FRAC_BITS; + x2 = (x2) >> FRAC_BITS; + y2 = (y2) >> FRAC_BITS; + + if (y1 > y2 || (y1 == y2 && x1 > x2)) { + long tmp; + + tmp=x1; + x1=x2; + x2=tmp; + + tmp=y1; + y1=y2; + y2=tmp; + } + + if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return; + if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return; + if (x1 == x2 && y1 == y2) return; // Bad !!! + + if (y1 < clip_rect.ymin && y1 != y2) { + x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1); + y1 = clip_rect.ymin; + } + + if (y2 > clip_rect.ymax && y1 != y2) { + x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1); + y2 = clip_rect.ymax; + } + + if (x1 < x2) { + if (x1 < clip_rect.xmin && x1 != x2) { + y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1); + x1 = clip_rect.xmin; + } + + if (x2 > clip_rect.xmax && x1 != x2) { + y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1); + x2 = clip_rect.xmax; + } + } + + if (x1 > x2) { + if (x2 < clip_rect.xmin && x2 != x1) { + y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2); + x2 = clip_rect.xmin; + } + + if (x1 > clip_rect.xmax && x2 != x1) { + y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2); + x1 = clip_rect.xmax; + } + } + + // Check again + if (x1 == x2 && y1 == y2) return; + if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return; + if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return; + if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return; + if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return; + + sx=bpl >> 1; + adr=(y1 * sx + x1); + pp = (TYPE *)canvasBuffer + adr; + + dx = x2 - x1; + dy = y2 - y1; + + color = allocColor(foregroundColor); + alpha = foregroundColor.alpha; + + if (alpha == ALPHA_OPAQUE) { + +#define PUTPIXEL() \ + { \ + *pp=color; \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1); a-=dx; }\ + else { pp+=(inc_2); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } else { +#define PUTPIXEL() \ + { \ + *pp=mix_alpha(*pp,color,alpha); \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1); a-=dx; }\ + else { pp+=(inc_2); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } +} diff --git a/core/multimedia/opieplayer/libflash/graphic16.h b/core/multimedia/opieplayer/libflash/graphic16.h new file mode 100644 index 0000000..938d856 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic16.h @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +class GraphicDevice16: public GraphicDevice { +private: + long GraphicDevice16::allocColor(Color color); + +public: + GraphicDevice16(FlashDisplay *fd); + + void clearCanvas(); + void fillLineAA(FillStyleDef *f, long y, long start, long end); + void fillLine(FillStyleDef *f, long y, long start, long end); + void fillLineBitmap(FillStyleDef *f, long y, long start, long end); + void fillLineLG(Gradient *grad, long y, long start, long end); + void fillLineRG(Gradient *grad, long y, long start, long end); + void drawLine(long x1, long y1, long x2, long y2, long width); +}; diff --git a/core/multimedia/opieplayer/libflash/graphic24.cc b/core/multimedia/opieplayer/libflash/graphic24.cc new file mode 100644 index 0000000..6d15019 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic24.cc @@ -0,0 +1,648 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#include "graphic24.h" + +extern unsigned char SQRT[]; + +#define FULL_AA + +#define PRINT 0 + +typedef unsigned char TYPE; +#define BPP 3 + +GraphicDevice24::GraphicDevice24(FlashDisplay *fd) : GraphicDevice(fd) +{ +} + +long +GraphicDevice24::allocColor(Color color) +{ + return 0; +} + +void +GraphicDevice24::clearCanvas() +{ + TYPE *point,*p; + long h, w,n; + + if (!bgInitialized) return; + + point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin*BPP; + w = clip_rect.xmax - clip_rect.xmin; + h = clip_rect.ymax - clip_rect.ymin; + + while (h--) { + p = point; + n = w; + while (n--) { + *p++ = backgroundColor.blue; + *p++ = backgroundColor.green; + *p++ = backgroundColor.red; + } + + point = (TYPE *)((char *)point + bpl); + } + + flashDisplay->flash_refresh = 1; + flashDisplay->clip_x = clip_rect.xmin; + flashDisplay->clip_y = clip_rect.ymin; + flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin; + flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin; +} + +/* alpha = 0 : select c1, alpha = 255 select c2 */ +static inline void mix_alpha(TYPE *c1, Color c2, int alpha) +{ + *c1 = (((c2.blue- (*c1))*alpha + (*c1) * 256) >> 8); + c1++; + *c1 = (((c2.green- (*c1))*alpha + (*c1) * 256) >> 8); + c1++; + *c1 = (((c2.red- (*c1))*alpha + (*c1) * 256) >> 8); +} + +void +GraphicDevice24::fillLineAA(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line; + TYPE *point; + Color pixel; + unsigned int alpha, start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + line = (TYPE *)(canvasBuffer + bpl*y); + + alpha = f->color.alpha; + pixel = f->color; + + if (alpha == ALPHA_OPAQUE) { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start*BPP]; + + if (start == end) { + mix_alpha(point, pixel, start_alpha + end_alpha - 255); + } else { + n = end-start; + if (start_alpha < 255) { + mix_alpha(point, pixel, start_alpha); + point += BPP; + n--; + } + while (n > 0) { + *point++ = pixel.blue; + *point++ = pixel.green; + *point++ = pixel.red; + n--; + } + if (end_alpha > 0) { + mix_alpha(point, pixel, end_alpha); + } + } + } else { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start*BPP]; + + if (start == end) { + mix_alpha(point, pixel, ((start_alpha + end_alpha - 255) * alpha) >> 8); + } else { + n = end-start; + if (start_alpha < 255) { + mix_alpha(point, pixel, (start_alpha * alpha) >> 8); + point+=BPP; + n--; + } + while (n > 0) { + mix_alpha(point, pixel, alpha); + point+=BPP; + n--; + } + if (end_alpha > 0) { + mix_alpha(point, pixel, (end_alpha * alpha) >> 8); + } + } + } +} + +void +GraphicDevice24::fillLine(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line,*point; + Color pixel; + unsigned int alpha; + + if (clip(y,start,end)) return; + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start*BPP]; + n = end-start; + alpha = f->color.alpha; + pixel = f->color; + if (alpha == ALPHA_OPAQUE) { + while (n--) { + *point++ = pixel.blue; + *point++ = pixel.green; + *point++ = pixel.red; + } + } else { + while (n--) { + mix_alpha(point, pixel, alpha); + point+=BPP; + } + } +} + +void +GraphicDevice24::fillLineBitmap(FillStyleDef *f, long y, long start, long end) +{ + int n; + long x1,y1,dx,dy; + Matrix *m = &f->bitmap_matrix; + Bitmap *b = f->bitmap; + unsigned char *pixels; + TYPE *p; + Color *cmap; + long pixbpl; + Color pixel; + int offset; + unsigned char *alpha_table; + + /* safety test) */ + if (!b) return; + + if (clip(y,start,end)) return; + + start /= FRAC; + end /= FRAC; + n = end - start; + p = (TYPE *) (canvasBuffer + bpl*y + start*BPP); + + x1 = (long) (m->a * start + m->b * y + m->tx); + y1 = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + pixels = b->pixels; + pixbpl = b->bpl; + cmap = f->cmap; + + if (b->alpha_buf == NULL) { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]]; + *p++ = pixel.blue; + *p++ = pixel.green; + *p++ = pixel.red; + } else { + p+=BPP; + } + x1 += dx; + y1 += dy; + n--; + } + } else if (f->alpha_table) { + alpha_table = f->alpha_table; + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + mix_alpha(p, cmap[pixels[offset]], alpha_table[b->alpha_buf[offset]]); + } + p+=BPP; + x1 += dx; + y1 += dy; + n--; + } + } else { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + mix_alpha(p, cmap[pixels[offset]], b->alpha_buf[offset]); + } + p+=BPP; + x1 += dx; + y1 += dy; + n--; + } + } +} + +void +GraphicDevice24::fillLineLG(Gradient *grad, long y, long start, long end) +{ + long dr,r,v,r2; + register long n; + TYPE *line; + TYPE *point; + Color *cp,*ramp; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + r = (long) (m->a * start + m->b * y + m->tx); + dr = (long) (m->a); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start*BPP]; + + r2 = r + n * dr; + if ( ((r | r2) & ~255) == 0 ) { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + mix_alpha(point, ramp[v], start_alpha); + point+=BPP; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + *point++ = ramp[v].blue; + *point++ = ramp[v].green; + *point++ = ramp[v].red; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + mix_alpha(point, ramp[v], end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + cp = &ramp[v]; + mix_alpha(point, *cp, cp->alpha); + point+=BPP; + r += dr; + } + } + } else { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + mix_alpha(point, ramp[v], start_alpha); + point+=BPP; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point++ = ramp[v].blue; + *point++ = ramp[v].green; + *point++ = ramp[v].red; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + mix_alpha(point, ramp[v], end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + cp = &ramp[v]; + mix_alpha(point, *cp, cp->alpha); + point+=BPP; + r += dr; + } + } + } +} + +void +GraphicDevice24::fillLineRG(Gradient *grad, long y, long start, long end) +{ + long X,dx,r,Y,dy; + long dist2; + register long n; + Color *cp,*ramp; + TYPE *line; + TYPE *point; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + X = (long) (m->a * start + m->b * y + m->tx); + Y = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start*BPP]; + + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start == end) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + mix_alpha(point, ramp[r], start_alpha + end_alpha - 255); + } else { + if (start_alpha < 255) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + mix_alpha(point, ramp[r], start_alpha); + point+=BPP; + X += dx; + Y += dy; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + *point++ = ramp[r].blue; + *point++ = ramp[r].green; + *point++ = ramp[r].red; + X += dx; + Y += dy; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + mix_alpha(point, ramp[r], end_alpha); + } + } +#endif /* FULL_AA */ + + } else { + while (n--) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + cp = &ramp[r]; + mix_alpha(point, *cp, cp->alpha); + point+=BPP; + X += dx; + Y += dy; + } + } +} + +void +GraphicDevice24::drawLine(long x1, long y1, long x2, long y2, long width) +{ + int n,adr,dx,dy,sx; + Color color; + register int a; + register TYPE *pp; + int alpha; + + x1 = (x1) >> FRAC_BITS; + y1 = (y1) >> FRAC_BITS; + x2 = (x2) >> FRAC_BITS; + y2 = (y2) >> FRAC_BITS; + + if (y1 > y2 || (y1 == y2 && x1 > x2)) { + long tmp; + + tmp=x1; + x1=x2; + x2=tmp; + + tmp=y1; + y1=y2; + y2=tmp; + } + + if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return; + if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return; + if (x1 == x2 && y1 == y2) return; // Bad !!! + + if (y1 < clip_rect.ymin && y1 != y2) { + x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1); + y1 = clip_rect.ymin; + } + + if (y2 > clip_rect.ymax && y1 != y2) { + x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1); + y2 = clip_rect.ymax; + } + + if (x1 < x2) { + if (x1 < clip_rect.xmin && x1 != x2) { + y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1); + x1 = clip_rect.xmin; + } + + if (x2 > clip_rect.xmax && x1 != x2) { + y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1); + x2 = clip_rect.xmax; + } + } + + if (x1 > x2) { + if (x2 < clip_rect.xmin && x2 != x1) { + y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2); + x2 = clip_rect.xmin; + } + + if (x1 > clip_rect.xmax && x2 != x1) { + y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2); + x1 = clip_rect.xmax; + } + } + + // Check again + if (x1 == x2 && y1 == y2) return; + if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return; + if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return; + if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return; + if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return; + + sx=bpl >> 1; + adr=(y1 * sx + x1); + pp = (TYPE *)canvasBuffer + adr; + + dx = x2 - x1; + dy = y2 - y1; + + color = foregroundColor; + alpha = foregroundColor.alpha; + + if (alpha == ALPHA_OPAQUE) { + +#define PUTPIXEL() \ + { \ + *pp++=color.red; \ + *pp++=color.green; \ + *pp++=color.blue; \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1); a-=dx; }\ + else { pp+=(inc_2); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } else { +#define PUTPIXEL() \ + { \ + mix_alpha(pp,color,alpha); \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1*BPP); a-=dx; }\ + else { pp+=(inc_2*BPP); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } +} diff --git a/core/multimedia/opieplayer/libflash/graphic24.h b/core/multimedia/opieplayer/libflash/graphic24.h new file mode 100644 index 0000000..4c10e49 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic24.h @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +class GraphicDevice24: public GraphicDevice { +private: + long GraphicDevice24::allocColor(Color color); + +public: + GraphicDevice24(FlashDisplay *fd); + + void clearCanvas(); + void fillLineAA(FillStyleDef *f, long y, long start, long end); + void fillLine(FillStyleDef *f, long y, long start, long end); + void fillLineBitmap(FillStyleDef *f, long y, long start, long end); + void fillLineLG(Gradient *grad, long y, long start, long end); + void fillLineRG(Gradient *grad, long y, long start, long end); + void drawLine(long x1, long y1, long x2, long y2, long width); +}; diff --git a/core/multimedia/opieplayer/libflash/graphic32.cc b/core/multimedia/opieplayer/libflash/graphic32.cc new file mode 100644 index 0000000..b9c2008 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic32.cc @@ -0,0 +1,657 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#include "graphic32.h" + +extern unsigned char SQRT[]; + +#define FULL_AA + +#define PRINT 0 + +typedef unsigned long TYPE; + +GraphicDevice32::GraphicDevice32(FlashDisplay *fd) : GraphicDevice(fd) +{ +} + +long +GraphicDevice32::allocColor(Color color) +{ + return (color.red)<<16 | (color.green)<<8 | (color.blue); +} + +void +GraphicDevice32::clearCanvas() +{ + TYPE pixel; + TYPE *point,*p; + long h, w,n; + + if (!bgInitialized) return; + + pixel = allocColor(backgroundColor); + + point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin; + w = clip_rect.xmax - clip_rect.xmin; + h = clip_rect.ymax - clip_rect.ymin; + + while (h--) { + p = point; + n = w; + while (n--) { + *p++ = pixel; + } + + point = (TYPE *)((char *)point + bpl); + } + + flashDisplay->flash_refresh = 1; + flashDisplay->clip_x = clip_rect.xmin; + flashDisplay->clip_y = clip_rect.ymin; + flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin; + flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin; +} + +#define RED_MASK 0xFF0000 +#define GREEN_MASK 0x00FF00 +#define BLUE_MASK 0x0000FF + +/* alpha = 0 : select c1, alpha = 255 select c2 */ +static inline unsigned long +mix_alpha(unsigned long c1, unsigned long c2, int alpha) +{ + long r1,r2,r; + long g1,g2,g; + long b1,b2,b; + + r1 = c1 & RED_MASK; + r2 = c2 & RED_MASK; + r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK; + + g1 = c1 & GREEN_MASK; + g2 = c2 & GREEN_MASK; + g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK; + + b1 = c1 & BLUE_MASK; + b2 = c2 & BLUE_MASK; + b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK; + + return (r|g|b); +} + +void +GraphicDevice32::fillLineAA(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line; + TYPE *point,pixel; + unsigned int alpha, start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + line = (TYPE *)(canvasBuffer + bpl*y); + + alpha = f->color.alpha; + pixel = f->color.pixel; + + if (alpha == ALPHA_OPAQUE) { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start]; + + if (start == end) { + *point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255); + } else { + n = end-start; + if (start_alpha < 255) { + *point = mix_alpha(*point, pixel, start_alpha); + point++; + n--; + } + while (n > 0) { + *point = pixel; + point++; + n--; + } + if (end_alpha > 0) { + *point = mix_alpha(*point, pixel, end_alpha); + } + } + } else { + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + point = &line[start]; + + if (start == end) { + *point = mix_alpha(*point, pixel, + ((start_alpha + end_alpha - 255) * alpha) >> 8); + } else { + n = end-start; + if (start_alpha < 255) { + *point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8); + point++; + n--; + } + while (n > 0) { + *point = mix_alpha(*point, pixel, alpha); + point++; + n--; + } + if (end_alpha > 0) { + *point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8); + } + } + } +} + +void +GraphicDevice32::fillLine(FillStyleDef *f, long y, long start, long end) +{ + register long n; + TYPE *line,*point; + TYPE pixel; + unsigned int alpha; + + if (clip(y,start,end)) return; + + start >>= FRAC_BITS; + end >>= FRAC_BITS; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + n = end-start; + pixel = f->color.pixel; + alpha = f->color.alpha; + if (alpha == ALPHA_OPAQUE) { + while (n--) { + *point = pixel; + point++; + } + } else { + while (n--) { + *point = mix_alpha(*point, pixel, alpha); + point++; + } + } +} + +void +GraphicDevice32::fillLineBitmap(FillStyleDef *f, long y, long start, long end) +{ + int n; + long x1,y1,dx,dy; + Matrix *m = &f->bitmap_matrix; + Bitmap *b = f->bitmap; + unsigned char *pixels; + TYPE *p; + Color *cmap; + long pixbpl; + TYPE pixel; + int offset; + unsigned char *alpha_table; + + /* safety test) */ + if (!b) return; + + if (clip(y,start,end)) return; + + start /= FRAC; + end /= FRAC; + n = end - start; + p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * sizeof(TYPE)); + + /* the coordinates in the image are normalized to 16 bits */ + x1 = (long) (m->a * start + m->b * y + m->tx); + y1 = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + pixels = b->pixels; + pixbpl = b->bpl; + cmap = f->cmap; + + if (b->alpha_buf == NULL) { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel; + *p = pixel; + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } else if (f->alpha_table) { + alpha_table = f->alpha_table; + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + pixel = cmap[pixels[offset]].pixel; + *p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]); + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } else { + while (n) { + if (x1 >= 0 && y1 >= 0 && + (x1 >> 16) < b->width && (y1 >> 16) < b->height) { + + offset = (y1 >> 16) * pixbpl + (x1 >> 16); + pixel = cmap[pixels[offset]].pixel; + *p = mix_alpha(*p, pixel, b->alpha_buf[offset]); + } + x1 += dx; + y1 += dy; + p++; + n--; + } + } +} + +void +GraphicDevice32::fillLineLG(Gradient *grad, long y, long start, long end) +{ + long dr,r,v,r2; + register long n; + TYPE *line; + TYPE *point; + Color *cp,*ramp; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + r = (long) (m->a * start + m->b * y + m->tx); + dr = (long) (m->a); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + + r2 = r + n * dr; + if ( ((r | r2) & ~255) == 0 ) { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha); + point++; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + *point = (TYPE)ramp[v].pixel; + point++; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + cp = &ramp[v]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + r += dr; + } + } + } else { + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start_alpha < 255) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha); + point++; + r += dr; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = (TYPE)ramp[v].pixel; + point++; + r += dr; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha); + } +#endif /* FULL_AA */ + } else { + while (n--) { + v = r>>16; + if (v < 0) v = 0; + else if (v > 255) v = 255; + cp = &ramp[v]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + r += dr; + } + } + } +} + +void +GraphicDevice32::fillLineRG(Gradient *grad, long y, long start, long end) +{ + long X,dx,r,Y,dy; + long dist2; + register long n; + Color *cp,*ramp; + TYPE *line; + TYPE *point; + Matrix *m = &grad->imat; + unsigned int start_alpha,end_alpha; + + if (clip(y,start,end)) return; + + start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS)); + end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS); + + start /= FRAC; + end /= FRAC; + + n = end-start; + + X = (long) (m->a * start + m->b * y + m->tx); + Y = (long) (m->c * start + m->d * y + m->ty); + dx = (long) (m->a); + dy = (long) (m->c); + + ramp = grad->ramp; + + line = (TYPE *)(canvasBuffer + bpl*y); + point = &line[start]; + + if (!grad->has_alpha) { +#ifdef FULL_AA + if (start == end) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r = SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255); + } else { + if (start_alpha < 255) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r = SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha); + point++; + X += dx; + Y += dy; + n--; + } +#endif /* FULL_AA */ + while (n>0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + *point = (TYPE)ramp[r].pixel; + point++; + X += dx; + Y += dy; + n--; + } +#ifdef FULL_AA + if (end_alpha > 0) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + *point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha); + } + } +#endif /* FULL_AA */ + + } else { + while (n--) { + dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16)); + if ((unsigned long)dist2 >= 65536) { + r = 255; + } else { + r= SQRT[dist2]; + } + cp = &ramp[r]; + *point = mix_alpha(*point, cp->pixel, cp->alpha); + point++; + X += dx; + Y += dy; + } + } +} + +void +GraphicDevice32::drawLine(long x1, long y1, long x2, long y2, long width) +{ + int n,adr,dx,dy,sx,color; + register int a; + register TYPE *pp; + int alpha; + + x1 = (x1) >> FRAC_BITS; + y1 = (y1) >> FRAC_BITS; + x2 = (x2) >> FRAC_BITS; + y2 = (y2) >> FRAC_BITS; + + if (y1 > y2 || (y1 == y2 && x1 > x2)) { + long tmp; + + tmp=x1; + x1=x2; + x2=tmp; + + tmp=y1; + y1=y2; + y2=tmp; + } + + if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return; + if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return; + if (x1 == x2 && y1 == y2) return; // Bad !!! + + if (y1 < clip_rect.ymin && y1 != y2) { + x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1); + y1 = clip_rect.ymin; + } + + if (y2 > clip_rect.ymax && y1 != y2) { + x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1); + y2 = clip_rect.ymax; + } + + if (x1 < x2) { + if (x1 < clip_rect.xmin && x1 != x2) { + y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1); + x1 = clip_rect.xmin; + } + + if (x2 > clip_rect.xmax && x1 != x2) { + y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1); + x2 = clip_rect.xmax; + } + } + + if (x1 > x2) { + if (x2 < clip_rect.xmin && x2 != x1) { + y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2); + x2 = clip_rect.xmin; + } + + if (x1 > clip_rect.xmax && x2 != x1) { + y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2); + x1 = clip_rect.xmax; + } + } + + // Check again + if (x1 == x2 && y1 == y2) return; + if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return; + if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return; + if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return; + if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return; + + sx=bpl >> 1; + adr=(y1 * sx + x1); + pp = (TYPE *)canvasBuffer + adr; + + dx = x2 - x1; + dy = y2 - y1; + + color = allocColor(foregroundColor); + alpha = foregroundColor.alpha; + + if (alpha == ALPHA_OPAQUE) { + +#define PUTPIXEL() \ + { \ + *pp=color; \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1); a-=dx; }\ + else { pp+=(inc_2); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } else { +#define PUTPIXEL() \ + { \ + *pp=mix_alpha(*pp,color,alpha); \ + } + +#define DRAWLINE(dx,dy,inc_1,inc_2) \ + n=dx;\ + a=2*dy-dx;\ + dy=2*dy;\ + dx=2*dx-dy;\ + do {\ + PUTPIXEL();\ + if (a>0) { pp+=(inc_1); a-=dx; }\ + else { pp+=(inc_2); a+=dy; }\ + } while (--n >= 0); + +/* fin macro */ + + if (dx == 0 && dy == 0) { + PUTPIXEL(); + } else if (dx > 0) { + if (dx >= dy) { + DRAWLINE(dx, dy, sx + 1, 1); + } else { + DRAWLINE(dy, dx, sx + 1, sx); + } + } else { + dx = -dx; + if (dx >= dy) { + DRAWLINE(dx, dy, sx - 1, -1); + } else { + DRAWLINE(dy, dx, sx - 1, sx); + } + } + + +#undef DRAWLINE +#undef PUTPIXEL + } +} diff --git a/core/multimedia/opieplayer/libflash/graphic32.h b/core/multimedia/opieplayer/libflash/graphic32.h new file mode 100644 index 0000000..3d75a4d --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/graphic32.h @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +class GraphicDevice32: public GraphicDevice { +private: + long GraphicDevice32::allocColor(Color color); + +public: + GraphicDevice32(FlashDisplay *fd); + + void clearCanvas(); + void fillLineAA(FillStyleDef *f, long y, long start, long end); + void fillLine(FillStyleDef *f, long y, long start, long end); + void fillLineBitmap(FillStyleDef *f, long y, long start, long end); + void fillLineLG(Gradient *grad, long y, long start, long end); + void fillLineRG(Gradient *grad, long y, long start, long end); + void drawLine(long x1, long y1, long x2, long y2, long width); +}; diff --git a/core/multimedia/opieplayer/libflash/jconfig.h b/core/multimedia/opieplayer/libflash/jconfig.h new file mode 100644 index 0000000..9594ec5 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/jconfig.h @@ -0,0 +1,45 @@ +/* jconfig.h. Generated automatically by configure. */ +/* jconfig.cfg --- source file edited by configure script */ +/* see jconfig.doc for explanations */ + +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +#undef void +#undef const +#undef CHAR_IS_UNSIGNED +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H +#undef NEED_BSD_STRINGS +#undef NEED_SYS_TYPES_H +#undef NEED_FAR_POINTERS +#undef NEED_SHORT_EXTERNAL_NAMES +/* Define this if you get warnings about undefined structures. */ +#undef INCOMPLETE_TYPES_BROKEN + +#ifdef JPEG_INTERNALS + +#undef RIGHT_SHIFT_IS_UNSIGNED +#define INLINE __inline__ +/* These are for configuring the JPEG memory manager. */ +#undef DEFAULT_MAX_MEM +#undef NO_MKTEMP + +#endif /* JPEG_INTERNALS */ + +#ifdef JPEG_CJPEG_DJPEG + +#define BMP_SUPPORTED /* BMP image file format */ +#define GIF_SUPPORTED /* GIF image file format */ +#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ +#undef RLE_SUPPORTED /* Utah RLE image file format */ +#define TARGA_SUPPORTED /* Targa image file format */ + +#undef TWO_FILE_COMMANDLINE +#undef NEED_SIGNAL_CATCHER +#undef DONT_USE_B_MODE + +/* Define this if you want percent-done progress reports from cjpeg/djpeg. */ +#undef PROGRESS_REPORT + +#endif /* JPEG_CJPEG_DJPEG */ diff --git a/core/multimedia/opieplayer/libflash/jerror.h b/core/multimedia/opieplayer/libflash/jerror.h new file mode 100644 index 0000000..fc2fffe --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/jerror.h @@ -0,0 +1,291 @@ +/* + * jerror.h + * + * Copyright (C) 1994-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the error and message codes for the JPEG library. + * Edit this file to add new codes, or to translate the message strings to + * some other language. + * A set of error-reporting macros are defined too. Some applications using + * the JPEG library may wish to include this file to get the error codes + * and/or the macros. + */ + +/* + * To define the enum list of message codes, include this file without + * defining macro JMESSAGE. To create a message string table, include it + * again with a suitable JMESSAGE definition (see jerror.c for an example). + */ +#ifndef JMESSAGE +#ifndef JERROR_H +/* First time through, define the enum list */ +#define JMAKE_ENUM_LIST +#else +/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ +#define JMESSAGE(code,string) +#endif /* JERROR_H */ +#endif /* JMESSAGE */ + +#ifdef JMAKE_ENUM_LIST + +typedef enum { + +#define JMESSAGE(code,string) code , + +#endif /* JMAKE_ENUM_LIST */ + +JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ + +/* For maintenance convenience, list is alphabetical by message code name */ +JMESSAGE(JERR_ARITH_NOTIMPL, + "Sorry, there are legal restrictions on arithmetic coding") +JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") +JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") +JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") +JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") +JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") +JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") +JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") +JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") +JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") +JMESSAGE(JERR_BAD_LIB_VERSION, + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") +JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") +JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") +JMESSAGE(JERR_BAD_PROGRESSION, + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_PROG_SCRIPT, + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") +JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") +JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") +JMESSAGE(JERR_BAD_STRUCT_SIZE, + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") +JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") +JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") +JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") +JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") +JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") +JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") +JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") +JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") +JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") +JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") +JMESSAGE(JERR_EMS_READ, "Read from EMS failed") +JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") +JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") +JMESSAGE(JERR_FILE_READ, "Input file read error") +JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") +JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") +JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") +JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") +JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") +JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") +JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") +JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, + "Cannot transcode due to multiple use of quantization table %d") +JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") +JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") +JMESSAGE(JERR_NOTIMPL, "Not implemented yet") +JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") +JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") +JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") +JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") +JMESSAGE(JERR_QUANT_COMPONENTS, + "Cannot quantize more than %d color components") +JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") +JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") +JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") +JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") +JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") +JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") +JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF") +JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") +JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") +JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") +JMESSAGE(JERR_TFILE_WRITE, + "Write failed on temporary file --- out of disk space?") +JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") +JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") +JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") +JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") +JMESSAGE(JERR_XMS_READ, "Read from XMS failed") +JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") +JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) +JMESSAGE(JMSG_VERSION, JVERSION) +JMESSAGE(JTRC_16BIT_TABLES, + "Caution: quantization tables are too coarse for baseline JPEG") +JMESSAGE(JTRC_ADOBE, + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") +JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") +JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") +JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") +JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") +JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") +JMESSAGE(JTRC_DRI, "Define Restart Interval %u") +JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") +JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") +JMESSAGE(JTRC_EOI, "End Of Image") +JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") +JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") +JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, + "Warning: thumbnail image size does not match data length %u") +JMESSAGE(JTRC_JFIF_EXTENSION, + "JFIF extension marker: type 0x%02x, length %u") +JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") +JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") +JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") +JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") +JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") +JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") +JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") +JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") +JMESSAGE(JTRC_RST, "RST%d") +JMESSAGE(JTRC_SMOOTH_NOTIMPL, + "Smoothing not supported with nonstandard sampling ratios") +JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") +JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") +JMESSAGE(JTRC_SOI, "Start of Image") +JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") +JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") +JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") +JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") +JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") +JMESSAGE(JTRC_THUMB_JPEG, + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_PALETTE, + "JFIF extension marker: palette thumbnail image, length %u") +JMESSAGE(JTRC_THUMB_RGB, + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") +JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") +JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") +JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_BOGUS_PROGRESSION, + "Inconsistent progression sequence for component %d coefficient %d") +JMESSAGE(JWRN_EXTRANEOUS_DATA, + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") +JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") +JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") +JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") +JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_RESYNC, + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") +JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") +JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") + +#ifdef JMAKE_ENUM_LIST + + JMSG_LASTMSGCODE +} J_MESSAGE_CODE; + +#undef JMAKE_ENUM_LIST +#endif /* JMAKE_ENUM_LIST */ + +/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ +#undef JMESSAGE + + +#ifndef JERROR_H +#define JERROR_H + +/* Macros to simplify using the error and trace message stuff */ +/* The first parameter is either type of cinfo pointer */ + +/* Fatal errors (print message and exit) */ +#define ERREXIT(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT3(cinfo,code,p1,p2,p3) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (cinfo)->err->msg_parm.i[2] = (p3), \ + (cinfo)->err->msg_parm.i[3] = (p4), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) +#define ERREXITS(cinfo,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) + +#define MAKESTMT(stuff) do { stuff } while (0) + +/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ +#define WARNMS(cinfo,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS1(cinfo,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) +#define WARNMS2(cinfo,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) + +/* Informational/debugging messages */ +#define TRACEMS(cinfo,lvl,code) \ + ((cinfo)->err->msg_code = (code), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS1(cinfo,lvl,code,p1) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS2(cinfo,lvl,code,p1,p2) \ + ((cinfo)->err->msg_code = (code), \ + (cinfo)->err->msg_parm.i[0] = (p1), \ + (cinfo)->err->msg_parm.i[1] = (p2), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) +#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ + MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) +#define TRACEMSS(cinfo,lvl,code,str) \ + ((cinfo)->err->msg_code = (code), \ + strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) + +#endif /* JERROR_H */ diff --git a/core/multimedia/opieplayer/libflash/jmorecfg.h b/core/multimedia/opieplayer/libflash/jmorecfg.h new file mode 100644 index 0000000..54a7d1c --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/jmorecfg.h @@ -0,0 +1,363 @@ +/* + * jmorecfg.h + * + * Copyright (C) 1991-1997, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains additional configuration options that customize the + * JPEG software for special applications or support machine-dependent + * optimizations. Most users will not need to touch this file. + */ + + +/* + * Define BITS_IN_JSAMPLE as either + * 8 for 8-bit sample values (the usual setting) + * 12 for 12-bit sample values + * Only 8 and 12 are legal data precisions for lossy JPEG according to the + * JPEG standard, and the IJG code does not support anything else! + * We do not support run-time selection of data precision, sorry. + */ + +#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ + + +/* + * Maximum number of components (color channels) allowed in JPEG image. + * To meet the letter of the JPEG spec, set this to 255. However, darn + * few applications need more than 4 channels (maybe 5 for CMYK + alpha + * mask). We recommend 10 as a reasonable compromise; use 4 if you are + * really short on memory. (Each allowed component costs a hundred or so + * bytes of storage, whether actually used in an image or not.) + */ + +#define MAX_COMPONENTS 10 /* maximum number of image components */ + + +/* + * Basic data types. + * You may need to change these if you have a machine with unusual data + * type sizes; for example, "char" not 8 bits, "short" not 16 bits, + * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, + * but it had better be at least 16. + */ + +/* Representation of a single sample (pixel element value). + * We frequently allocate large arrays of these, so it's important to keep + * them small. But if you have memory to burn and access to char or short + * arrays is very slow on your hardware, you might want to change these. + */ + +#if BITS_IN_JSAMPLE == 8 +/* JSAMPLE should be the smallest type that will hold the values 0..255. + * You can use a signed char by having GETJSAMPLE mask it with 0xFF. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JSAMPLE; +#ifdef CHAR_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + +#define MAXJSAMPLE 255 +#define CENTERJSAMPLE 128 + +#endif /* BITS_IN_JSAMPLE == 8 */ + + +#if BITS_IN_JSAMPLE == 12 +/* JSAMPLE should be the smallest type that will hold the values 0..4095. + * On nearly all machines "short" will do nicely. + */ + +typedef short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#define MAXJSAMPLE 4095 +#define CENTERJSAMPLE 2048 + +#endif /* BITS_IN_JSAMPLE == 12 */ + + +/* Representation of a DCT frequency coefficient. + * This should be a signed value of at least 16 bits; "short" is usually OK. + * Again, we allocate large arrays of these, but you can change to int + * if you have memory to burn and "short" is really slow. + */ + +typedef short JCOEF; + + +/* Compressed datastreams are represented as arrays of JOCTET. + * These must be EXACTLY 8 bits wide, at least once they are written to + * external storage. Note that when using the stdio data source/destination + * managers, this is also the data type passed to fread/fwrite. + */ + +#ifdef HAVE_UNSIGNED_CHAR + +typedef unsigned char JOCTET; +#define GETJOCTET(value) (value) + +#else /* not HAVE_UNSIGNED_CHAR */ + +typedef char JOCTET; +#ifdef CHAR_IS_UNSIGNED +#define GETJOCTET(value) (value) +#else +#define GETJOCTET(value) ((value) & 0xFF) +#endif /* CHAR_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_CHAR */ + + +/* These typedefs are used for various table entries and so forth. + * They must be at least as wide as specified; but making them too big + * won't cost a huge amount of memory, so we don't provide special + * extraction code like we did for JSAMPLE. (In other words, these + * typedefs live at a different point on the speed/space tradeoff curve.) + */ + +/* UINT8 must hold at least the values 0..255. */ + +#ifdef HAVE_UNSIGNED_CHAR +typedef unsigned char UINT8; +#else /* not HAVE_UNSIGNED_CHAR */ +#ifdef CHAR_IS_UNSIGNED +typedef char UINT8; +#else /* not CHAR_IS_UNSIGNED */ +typedef short UINT8; +#endif /* CHAR_IS_UNSIGNED */ +#endif /* HAVE_UNSIGNED_CHAR */ + +/* UINT16 must hold at least the values 0..65535. */ + +#ifdef HAVE_UNSIGNED_SHORT +typedef unsigned short UINT16; +#else /* not HAVE_UNSIGNED_SHORT */ +typedef unsigned int UINT16; +#endif /* HAVE_UNSIGNED_SHORT */ + +/* INT16 must hold at least the values -32768..32767. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ +typedef short INT16; +#endif + +/* INT32 must hold at least signed 32-bit values. */ + +#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ +typedef long INT32; +#endif + +/* Datatype used for image dimensions. The JPEG standard only supports + * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore + * "unsigned int" is sufficient on all machines. However, if you need to + * handle larger images and you don't mind deviating from the spec, you + * can change this datatype. + */ + +typedef unsigned int JDIMENSION; + +#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ + + +/* These macros are used in all function definitions and extern declarations. + * You could modify them if you need to change function linkage conventions; + * in particular, you'll need to do that to make the library a Windows DLL. + * Another application is to make all functions global for use with debuggers + * or code profilers that require it. + */ + +/* a function called through method pointers: */ +#define METHODDEF(type) static type +/* a function used only in its module: */ +#define LOCAL(type) static type +/* a function referenced thru EXTERNs: */ +#define GLOBAL(type) type +/* a reference to a GLOBAL function: */ +#define EXTERN(type) extern type + + +/* This macro is used to declare a "method", that is, a function pointer. + * We want to supply prototype parameters if the compiler can cope. + * Note that the arglist parameter must be parenthesized! + * Again, you can customize this if you need special linkage keywords. + */ + +#ifdef HAVE_PROTOTYPES +#define JMETHOD(type,methodname,arglist) type (*methodname) arglist +#else +#define JMETHOD(type,methodname,arglist) type (*methodname) () +#endif + + +/* Here is the pseudo-keyword for declaring pointers that must be "far" + * on 80x86 machines. Most of the specialized coding for 80x86 is handled + * by just saying "FAR *" where such a pointer is needed. In a few places + * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. + */ + +#ifdef NEED_FAR_POINTERS +#define FAR far +#else +#define FAR +#endif + + +/* + * On a few systems, type boolean and/or its values FALSE, TRUE may appear + * in standard header files. Or you may have conflicts with application- + * specific header files that you want to include together with these files. + * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. + */ + +#ifndef HAVE_BOOLEAN +typedef int boolean; +#endif +#ifndef FALSE /* in case these macros already exist */ +#define FALSE 0 /* values of boolean */ +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/* + * The remaining options affect code selection within the JPEG library, + * but they don't need to be visible to most applications using the library. + * To minimize application namespace pollution, the symbols won't be + * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. + */ + +#ifdef JPEG_INTERNALS +#define JPEG_INTERNAL_OPTIONS +#endif + +#ifdef JPEG_INTERNAL_OPTIONS + + +/* + * These defines indicate whether to include various optional functions. + * Undefining some of these symbols will produce a smaller but less capable + * library. Note that you can leave certain source files out of the + * compilation/linking process if you've #undef'd the corresponding symbols. + * (You may HAVE to do that if your compiler doesn't like null source files.) + */ + +/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ + +/* Capability options common to encoder and decoder: */ + +#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ +#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ +#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ + +/* Encoder capability options: */ + +#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ +/* Note: if you selected 12-bit data precision, it is dangerous to turn off + * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit + * precision, so jchuff.c normally uses entropy optimization to compute + * usable tables for higher precision. If you don't want to do optimization, + * you'll have to supply different default Huffman tables. + * The exact same statements apply for progressive JPEG: the default tables + * don't work for progressive mode. (This may get fixed, however.) + */ +#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ + +/* Decoder capability options: */ + +#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ +#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ +#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ +#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ +#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ +#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ +#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ +#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ +#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ + +/* more capability options later, no doubt */ + + +/* + * Ordering of RGB data in scanlines passed to or from the application. + * If your application wants to deal with data in the order B,G,R, just + * change these macros. You can also deal with formats such as R,G,B,X + * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing + * the offsets will also change the order in which colormap data is organized. + * RESTRICTIONS: + * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. + * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not + * useful if you are using JPEG color spaces other than YCbCr or grayscale. + * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE + * is not 3 (they don't understand about dummy color components!). So you + * can't use color quantization if you change that value. + */ + +#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ +#define RGB_GREEN 1 /* Offset of Green */ +#define RGB_BLUE 2 /* Offset of Blue */ +#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ + + +/* Definitions for speed-related optimizations. */ + + +/* If your compiler supports inline functions, define INLINE + * as the inline keyword; otherwise define it as empty. + */ + +#ifndef INLINE +#ifdef __GNUC__ /* for instance, GNU C knows about inline */ +#define INLINE __inline__ +#endif +#ifndef INLINE +#define INLINE /* default is to define it as empty */ +#endif +#endif + + +/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying + * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER + * as short on such a machine. MULTIPLIER must be at least 16 bits wide. + */ + +#ifndef MULTIPLIER +#define MULTIPLIER int /* type for fastest integer multiply */ +#endif + + +/* FAST_FLOAT should be either float or double, whichever is done faster + * by your compiler. (Note that this type is only used in the floating point + * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) + * Typically, float is faster in ANSI C compilers, while double is faster in + * pre-ANSI compilers (because they insist on converting to double anyway). + * The code below therefore chooses float if we have ANSI-style prototypes. + */ + +#ifndef FAST_FLOAT +#ifdef HAVE_PROTOTYPES +#define FAST_FLOAT float +#else +#define FAST_FLOAT double +#endif +#endif + +#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/core/multimedia/opieplayer/libflash/jpeglib.h b/core/multimedia/opieplayer/libflash/jpeglib.h new file mode 100644 index 0000000..d1be8dd --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/jpeglib.h @@ -0,0 +1,1096 @@ +/* + * jpeglib.h + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file defines the application interface for the JPEG library. + * Most applications using the library need only include this file, + * and perhaps jerror.h if they want to know the exact error codes. + */ + +#ifndef JPEGLIB_H +#define JPEGLIB_H + +/* + * First we include the configuration files that record how this + * installation of the JPEG library is set up. jconfig.h can be + * generated automatically for many systems. jmorecfg.h contains + * manual configuration options that most people need not worry about. + */ + +#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ +#include "jconfig.h" /* widely used configuration options */ +#endif +#include "jmorecfg.h" /* seldom changed options */ + + +/* Version ID for the JPEG library. + * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". + */ + +#define JPEG_LIB_VERSION 62 /* Version 6b */ + + +/* Various constants determining the sizes of things. + * All of these are specified by the JPEG standard, so don't change them + * if you want to be compatible. + */ + +#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ +#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ +#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ +#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ +#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ +#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ +#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ +/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; + * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. + * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU + * to handle it. We even let you do this from the jconfig.h file. However, + * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * sometimes emits noncompliant files doesn't mean you should too. + */ +#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ +#ifndef D_MAX_BLOCKS_IN_MCU +#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#endif + + +/* Data structures for images (arrays of samples and of DCT coefficients). + * On 80x86 machines, the image arrays are too big for near pointers, + * but the pointer arrays can fit in near memory. + */ + +typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ +typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ +typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ + +typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ +typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ +typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ + +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + + +/* Types for JPEG compression parameters and working tables. */ + + +/* DCT coefficient quantization tables. */ + +typedef struct { + /* This array gives the coefficient quantizers in natural array order + * (not the zigzag order in which they are stored in a JPEG DQT marker). + * CAUTION: IJG versions prior to v6a kept this array in zigzag order. + */ + UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JQUANT_TBL; + + +/* Huffman coding tables. */ + +typedef struct { + /* These two fields directly represent the contents of a JPEG DHT marker */ + UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ + /* length k bits; bits[0] is unused */ + UINT8 huffval[256]; /* The symbols, in order of incr code length */ + /* This field is used only during compression. It's initialized FALSE when + * the table is created, and set TRUE when it's been output to the file. + * You could suppress output of a table by setting this to TRUE. + * (See jpeg_suppress_tables for an example.) + */ + boolean sent_table; /* TRUE when table has been output */ +} JHUFF_TBL; + + +/* Basic info about one component (color channel). */ + +typedef struct { + /* These values are fixed over the whole image. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOF marker. */ + int component_id; /* identifier for this component (0..255) */ + int component_index; /* its index in SOF or cinfo->comp_info[] */ + int h_samp_factor; /* horizontal sampling factor (1..4) */ + int v_samp_factor; /* vertical sampling factor (1..4) */ + int quant_tbl_no; /* quantization table selector (0..3) */ + /* These values may vary between scans. */ + /* For compression, they must be supplied by parameter setup; */ + /* for decompression, they are read from the SOS marker. */ + /* The decompressor output side may not use these variables. */ + int dc_tbl_no; /* DC entropy table selector (0..3) */ + int ac_tbl_no; /* AC entropy table selector (0..3) */ + + /* Remaining fields should be treated as private by applications. */ + + /* These values are computed during compression or decompression startup: */ + /* Component's size in DCT blocks. + * Any dummy blocks added to complete an MCU are not counted; therefore + * these values do not depend on whether a scan is interleaved or not. + */ + JDIMENSION width_in_blocks; + JDIMENSION height_in_blocks; + /* Size of a DCT block in samples. Always DCTSIZE for compression. + * For decompression this is the size of the output from one DCT block, + * reflecting any scaling we choose to apply during the IDCT step. + * Values of 1,2,4,8 are likely to be supported. Note that different + * components may receive different IDCT scalings. + */ + int DCT_scaled_size; + /* The downsampled dimensions are the component's actual, unpadded number + * of samples at the main buffer (preprocessing/compression interface), thus + * downsampled_width = ceil(image_width * Hi/Hmax) + * and similarly for height. For decompression, IDCT scaling is included, so + * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + */ + JDIMENSION downsampled_width; /* actual width in samples */ + JDIMENSION downsampled_height; /* actual height in samples */ + /* This flag is used only for decompression. In cases where some of the + * components will be ignored (eg grayscale output from YCbCr image), + * we can skip most computations for the unused components. + */ + boolean component_needed; /* do we need the value of this component? */ + + /* These values are computed before starting a scan of the component. */ + /* The decompressor output side may not use these variables. */ + int MCU_width; /* number of blocks per MCU, horizontally */ + int MCU_height; /* number of blocks per MCU, vertically */ + int MCU_blocks; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ + int last_col_width; /* # of non-dummy blocks across in last MCU */ + int last_row_height; /* # of non-dummy blocks down in last MCU */ + + /* Saved quantization table for component; NULL if none yet saved. + * See jdinput.c comments about the need for this information. + * This field is currently used only for decompression. + */ + JQUANT_TBL * quant_table; + + /* Private per-component storage for DCT or IDCT subsystem. */ + void * dct_table; +} jpeg_component_info; + + +/* The script for encoding a multiple-scan file is an array of these: */ + +typedef struct { + int comps_in_scan; /* number of components encoded in this scan */ + int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ + int Ss, Se; /* progressive JPEG spectral selection parms */ + int Ah, Al; /* progressive JPEG successive approx. parms */ +} jpeg_scan_info; + +/* The decompressor can save APPn and COM markers in a list of these: */ + +typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; + +struct jpeg_marker_struct { + jpeg_saved_marker_ptr next; /* next in list, or NULL */ + UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ + unsigned int original_length; /* # bytes of data in the file */ + unsigned int data_length; /* # bytes of data saved at data[] */ + JOCTET FAR * data; /* the data contained in the marker */ + /* the marker length word is not counted in data_length or original_length */ +}; + +/* Known color spaces. */ + +typedef enum { + JCS_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ +} J_COLOR_SPACE; + +/* DCT/IDCT algorithm options. */ + +typedef enum { + JDCT_ISLOW, /* slow but accurate integer algorithm */ + JDCT_IFAST, /* faster, less accurate integer method */ + JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ +} J_DCT_METHOD; + +#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ +#define JDCT_DEFAULT JDCT_ISLOW +#endif +#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ +#define JDCT_FASTEST JDCT_IFAST +#endif + +/* Dithering options for decompression. */ + +typedef enum { + JDITHER_NONE, /* no dithering */ + JDITHER_ORDERED, /* simple ordered dither */ + JDITHER_FS /* Floyd-Steinberg error diffusion dither */ +} J_DITHER_MODE; + + +/* Common fields between JPEG compression and decompression master structs. */ + +#define jpeg_common_fields \ + struct jpeg_error_mgr * err; /* Error handler module */\ + struct jpeg_memory_mgr * mem; /* Memory manager module */\ + struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ + void * client_data; /* Available for use by application */\ + boolean is_decompressor; /* So common code can tell which is which */\ + int global_state /* For checking call sequence validity */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. + */ +struct jpeg_common_struct { + jpeg_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual jpeg_compress_struct or + * jpeg_decompress_struct. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct jpeg_common_struct * j_common_ptr; +typedef struct jpeg_compress_struct * j_compress_ptr; +typedef struct jpeg_decompress_struct * j_decompress_ptr; + + +/* Master record for a compression instance */ + +struct jpeg_compress_struct { + jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ + + /* Destination for compressed data */ + struct jpeg_destination_mgr * dest; + + /* Description of source image --- these fields must be filled in by + * outer application before starting compression. in_color_space must + * be correct before you can even call jpeg_set_defaults(). + */ + + JDIMENSION image_width; /* input image width */ + JDIMENSION image_height; /* input image height */ + int input_components; /* # of color components in input image */ + J_COLOR_SPACE in_color_space; /* colorspace of input image */ + + double input_gamma; /* image gamma of input image */ + + /* Compression parameters --- these fields must be set before calling + * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to + * initialize everything to reasonable defaults, then changing anything + * the application specifically wants to change. That way you won't get + * burnt when new parameters are added. Also note that there are several + * helper routines to simplify changing parameters. + */ + + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + int num_scans; /* # of entries in scan_info array */ + const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ + /* The default value of scan_info is NULL, which causes a single-scan + * sequential JPEG file to be emitted. To create a multi-scan file, + * set num_scans and scan_info to point to an array of scan definitions. + */ + + boolean raw_data_in; /* TRUE=caller supplies downsampled data */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ + + /* The restart interval can be specified in absolute MCUs by setting + * restart_interval, or in MCU rows by setting restart_in_rows + * (in which case the correct restart_interval will be figured + * for each scan). + */ + unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ + int restart_in_rows; /* if > 0, MCU rows per restart interval */ + + /* Parameters controlling emission of special markers. */ + + boolean write_JFIF_header; /* should a JFIF marker be written? */ + UINT8 JFIF_major_version; /* What to write for the JFIF version number */ + UINT8 JFIF_minor_version; + /* These three values are not used by the JPEG code, merely copied */ + /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ + /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ + /* ratio is defined by X_density/Y_density even when density_unit=0. */ + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean write_Adobe_marker; /* should an Adobe marker be written? */ + + /* State variable: index of next scanline to be written to + * jpeg_write_scanlines(). Application may use this to control its + * processing loop, e.g., "while (next_scanline < image_height)". + */ + + JDIMENSION next_scanline; /* 0 .. image_height-1 */ + + /* Remaining fields are known throughout compressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during compression startup + */ + boolean progressive_mode; /* TRUE if scan script uses progressive mode */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ + /* The coefficient controller receives data in units of MCU rows as defined + * for fully interleaved scans (whether the JPEG file is interleaved or not). + * There are v_samp_factor * DCTSIZE sample rows of each component in an + * "iMCU" (interleaved MCU) row. + */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[C_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* + * Links to compression subobjects (methods and private variables of modules) + */ + struct jpeg_comp_master * master; + struct jpeg_c_main_controller * main; + struct jpeg_c_prep_controller * prep; + struct jpeg_c_coef_controller * coef; + struct jpeg_marker_writer * marker; + struct jpeg_color_converter * cconvert; + struct jpeg_downsampler * downsample; + struct jpeg_forward_dct * fdct; + struct jpeg_entropy_encoder * entropy; + jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ + int script_space_size; +}; + + +/* Master record for a decompression instance */ + +struct jpeg_decompress_struct { + jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ + + /* Source of compressed data */ + struct jpeg_source_mgr * src; + + /* Basic description of image --- filled in by jpeg_read_header(). */ + /* Application may inspect these values to decide how to process image. */ + + JDIMENSION image_width; /* nominal image width (from SOF marker) */ + JDIMENSION image_height; /* nominal image height */ + int num_components; /* # of color components in JPEG image */ + J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ + + /* Decompression processing parameters --- these fields must be set before + * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes + * them to default values. + */ + + J_COLOR_SPACE out_color_space; /* colorspace for output */ + + unsigned int scale_num, scale_denom; /* fraction by which to scale image */ + + double output_gamma; /* image gamma wanted in output */ + + boolean buffered_image; /* TRUE=multiple output passes */ + boolean raw_data_out; /* TRUE=downsampled data wanted */ + + J_DCT_METHOD dct_method; /* IDCT algorithm selector */ + boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ + boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ + + boolean quantize_colors; /* TRUE=colormapped output wanted */ + /* the following are ignored if not quantize_colors: */ + J_DITHER_MODE dither_mode; /* type of color dithering to use */ + boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ + int desired_number_of_colors; /* max # colors to use in created colormap */ + /* these are significant only in buffered-image mode: */ + boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ + boolean enable_external_quant;/* enable future use of external colormap */ + boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ + + /* Description of actual output image that will be returned to application. + * These fields are computed by jpeg_start_decompress(). + * You can also use jpeg_calc_output_dimensions() to determine these values + * in advance of calling jpeg_start_decompress(). + */ + + JDIMENSION output_width; /* scaled image width */ + JDIMENSION output_height; /* scaled image height */ + int out_color_components; /* # of color components in out_color_space */ + int output_components; /* # of color components returned */ + /* output_components is 1 (a colormap index) when quantizing colors; + * otherwise it equals out_color_components. + */ + int rec_outbuf_height; /* min recommended height of scanline buffer */ + /* If the buffer passed to jpeg_read_scanlines() is less than this many rows + * high, space and time will be wasted due to unnecessary data copying. + * Usually rec_outbuf_height will be 1 or 2, at most 4. + */ + + /* When quantizing colors, the output colormap is described by these fields. + * The application can supply a colormap by setting colormap non-NULL before + * calling jpeg_start_decompress; otherwise a colormap is created during + * jpeg_start_decompress or jpeg_start_output. + * The map has out_color_components rows and actual_number_of_colors columns. + */ + int actual_number_of_colors; /* number of entries in use */ + JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ + + /* State variables: these variables indicate the progress of decompression. + * The application may examine these but must not modify them. + */ + + /* Row index of next scanline to be read from jpeg_read_scanlines(). + * Application may use this to control its processing loop, e.g., + * "while (output_scanline < output_height)". + */ + JDIMENSION output_scanline; /* 0 .. output_height-1 */ + + /* Current input scan number and number of iMCU rows completed in scan. + * These indicate the progress of the decompressor input side. + */ + int input_scan_number; /* Number of SOS markers seen so far */ + JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ + + /* The "output scan number" is the notional scan being displayed by the + * output side. The decompressor will not allow output scan/row number + * to get ahead of input scan/row, but it can fall arbitrarily far behind. + */ + int output_scan_number; /* Nominal scan number being displayed */ + JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ + + /* Current progression status. coef_bits[c][i] indicates the precision + * with which component c's DCT coefficient i (in zigzag order) is known. + * It is -1 when no data has yet been received, otherwise it is the point + * transform (shift) value for the most recent scan of the coefficient + * (thus, 0 at completion of the progression). + * This pointer is NULL when reading a non-progressive file. + */ + int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ + + /* Internal JPEG parameters --- the application usually need not look at + * these fields. Note that the decompressor output side may not use + * any parameters that can change between scans. + */ + + /* Quantization and Huffman tables are carried forward across input + * datastreams when processing abbreviated JPEG datastreams. + */ + + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; + /* ptrs to coefficient quantization tables, or NULL if not defined */ + + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; + JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; + /* ptrs to Huffman coding tables, or NULL if not defined */ + + /* These parameters are never carried across datastreams, since they + * are given in SOF/SOS markers or defined to be reset by SOI. + */ + + int data_precision; /* bits of precision in image data */ + + jpeg_component_info * comp_info; + /* comp_info[i] describes component that appears i'th in SOF */ + + boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ + boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ + UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ + UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ + + unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ + + /* These fields record data obtained from optional markers recognized by + * the JPEG library. + */ + boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ + /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ + UINT8 JFIF_major_version; /* JFIF version number */ + UINT8 JFIF_minor_version; + UINT8 density_unit; /* JFIF code for pixel size units */ + UINT16 X_density; /* Horizontal pixel density */ + UINT16 Y_density; /* Vertical pixel density */ + boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ + UINT8 Adobe_transform; /* Color transform code from Adobe marker */ + + boolean CCIR601_sampling; /* TRUE=first samples are cosited */ + + /* Aside from the specific data retained from APPn markers known to the + * library, the uninterpreted contents of any or all APPn and COM markers + * can be saved in a list for examination by the application. + */ + jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ + + /* Remaining fields are known throughout decompressor, but generally + * should not be touched by a surrounding application. + */ + + /* + * These fields are computed during decompression startup + */ + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The coefficient controller's input and output progress is measured in + * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows + * in fully interleaved JPEG scans, but are used whether the scan is + * interleaved or not. We define an iMCU row as v_samp_factor DCT block + * rows of each component. Therefore, the IDCT output contains + * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + */ + + JSAMPLE * sample_range_limit; /* table for fast range-limiting */ + + /* + * These fields are valid during any one scan. + * They describe the components and MCUs actually appearing in the scan. + * Note that the decompressor output side must not use these fields. + */ + int comps_in_scan; /* # of JPEG components in this scan */ + jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; + /* *cur_comp_info[i] describes component that appears i'th in SOS */ + + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ + JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ + + int blocks_in_MCU; /* # of DCT blocks per MCU */ + int MCU_membership[D_MAX_BLOCKS_IN_MCU]; + /* MCU_membership[i] is index in cur_comp_info of component owning */ + /* i'th block in an MCU */ + + int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + + /* This field is shared between entropy decoder and marker parser. + * It is either zero or the code of a JPEG marker that has been + * read from the data source, but has not yet been processed. + */ + int unread_marker; + + /* + * Links to decompression subobjects (methods, private variables of modules) + */ + struct jpeg_decomp_master * master; + struct jpeg_d_main_controller * main; + struct jpeg_d_coef_controller * coef; + struct jpeg_d_post_controller * post; + struct jpeg_input_controller * inputctl; + struct jpeg_marker_reader * marker; + struct jpeg_entropy_decoder * entropy; + struct jpeg_inverse_dct * idct; + struct jpeg_upsampler * upsample; + struct jpeg_color_deconverter * cconvert; + struct jpeg_color_quantizer * cquantize; +}; + + +/* "Object" declarations for JPEG modules that may be supplied or called + * directly by the surrounding application. + * As with all objects in the JPEG library, these structs only define the + * publicly visible methods and state variables of a module. Additional + * private fields may exist after the public ones. + */ + + +/* Error handler object */ + +struct jpeg_error_mgr { + /* Error exit handler: does not return to caller */ + JMETHOD(void, error_exit, (j_common_ptr cinfo)); + /* Conditionally emit a trace or warning message */ + JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); + /* Routine that actually outputs a trace or error message */ + JMETHOD(void, output_message, (j_common_ptr cinfo)); + /* Format a message string for the most recent JPEG error or message */ + JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); +#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ + /* Reset error state variables at start of a new image */ + JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); + + /* The message ID code and any parameters are saved here. + * A message can have one string parameter or up to 8 int parameters. + */ + int msg_code; +#define JMSG_STR_PARM_MAX 80 + union { + int i[8]; + char s[JMSG_STR_PARM_MAX]; + } msg_parm; + + /* Standard state variables for error facility */ + + int trace_level; /* max msg_level that will be displayed */ + + /* For recoverable corrupt-data errors, we emit a warning message, + * but keep going unless emit_message chooses to abort. emit_message + * should count warnings in num_warnings. The surrounding application + * can check for bad data by seeing if num_warnings is nonzero at the + * end of processing. + */ + long num_warnings; /* number of corrupt-data warnings */ + + /* These fields point to the table(s) of error message strings. + * An application can change the table pointer to switch to a different + * message list (typically, to change the language in which errors are + * reported). Some applications may wish to add additional error codes + * that will be handled by the JPEG library error mechanism; the second + * table pointer is used for this purpose. + * + * First table includes all errors generated by JPEG library itself. + * Error code 0 is reserved for a "no such error string" message. + */ + const char * const * jpeg_message_table; /* Library errors */ + int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ + /* Second table can be added by application (see cjpeg/djpeg for example). + * It contains strings numbered first_addon_message..last_addon_message. + */ + const char * const * addon_message_table; /* Non-library errors */ + int first_addon_message; /* code for first string in addon table */ + int last_addon_message; /* code for last string in addon table */ +}; + + +/* Progress monitor object */ + +struct jpeg_progress_mgr { + JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); + + long pass_counter; /* work units completed in this pass */ + long pass_limit; /* total number of work units in this pass */ + int completed_passes; /* passes completed so far */ + int total_passes; /* total number of passes expected */ +}; + + +/* Data destination object for compression */ + +struct jpeg_destination_mgr { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + + JMETHOD(void, init_destination, (j_compress_ptr cinfo)); + JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); + JMETHOD(void, term_destination, (j_compress_ptr cinfo)); +}; + + +/* Data source object for decompression */ + +struct jpeg_source_mgr { + const JOCTET * next_input_byte; /* => next byte to read from buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in buffer */ + + JMETHOD(void, init_source, (j_decompress_ptr cinfo)); + JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); + JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); + JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); + JMETHOD(void, term_source, (j_decompress_ptr cinfo)); +}; + + +/* Memory manager object. + * Allocates "small" objects (a few K total), "large" objects (tens of K), + * and "really big" objects (virtual arrays with backing store if needed). + * The memory manager does not allow individual objects to be freed; rather, + * each created object is assigned to a pool, and whole pools can be freed + * at once. This is faster and more convenient than remembering exactly what + * to free, especially where malloc()/free() are not too speedy. + * NB: alloc routines never return NULL. They exit to error_exit if not + * successful. + */ + +#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ +#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ +#define JPOOL_NUMPOOLS 2 + +typedef struct jvirt_sarray_control * jvirt_sarray_ptr; +typedef struct jvirt_barray_control * jvirt_barray_ptr; + + +struct jpeg_memory_mgr { + /* Method pointers */ + JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, + size_t sizeofobject)); + JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, + JDIMENSION samplesperrow, + JDIMENSION numrows)); + JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, + JDIMENSION blocksperrow, + JDIMENSION numrows)); + JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, + int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); + JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); + JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); + JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); + JMETHOD(void, self_destruct, (j_common_ptr cinfo)); + + /* Limit on memory allocation for this JPEG object. (Note that this is + * merely advisory, not a guaranteed maximum; it only affects the space + * used for virtual-array buffers.) May be changed by outer application + * after creating the JPEG object. + */ + long max_memory_to_use; + + /* Maximum allocation request accepted by alloc_large. */ + long max_alloc_chunk; +}; + + +/* Routine signature for application-supplied marker processing methods. + * Need not pass marker code since it is stored in cinfo->unread_marker. + */ +typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); + + +/* Declarations for routines called by application. + * The JPP macro hides prototype parameters from compilers that can't cope. + * Note JPP requires double parentheses. + */ + +#ifdef HAVE_PROTOTYPES +#define JPP(arglist) arglist +#else +#define JPP(arglist) () +#endif + + +/* Short forms of external names for systems with brain-damaged linkers. + * We shorten external names to be unique in the first six letters, which + * is good enough for all known systems. + * (If your compiler itself needs names to be unique in less than 15 + * characters, you are out of luck. Get a better compiler.) + */ + +#ifdef NEED_SHORT_EXTERNAL_NAMES +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart +#endif /* NEED_SHORT_EXTERNAL_NAMES */ + + +/* Default error-management setup */ +EXTERN(struct jpeg_error_mgr *) jpeg_std_error + JPP((struct jpeg_error_mgr * err)); + +/* Initialization of JPEG compression objects. + * jpeg_create_compress() and jpeg_create_decompress() are the exported + * names that applications should call. These expand to calls on + * jpeg_CreateCompress and jpeg_CreateDecompress with additional information + * passed for version mismatch checking. + * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. + */ +#define jpeg_create_compress(cinfo) \ + jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_compress_struct)) +#define jpeg_create_decompress(cinfo) \ + jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ + (size_t) sizeof(struct jpeg_decompress_struct)) +EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, + int version, size_t structsize)); +EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, + int version, size_t structsize)); +/* Destruction of JPEG compression objects */ +EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); + +/* Standard data source and destination managers: stdio streams. */ +/* Caller is responsible for opening the file before and closing after. */ +EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); +EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); + +/* Default parameter setup for compression */ +EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); +/* Compression parameter setup aids */ +EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, + J_COLOR_SPACE colorspace)); +EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, + boolean force_baseline)); +EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, + int scale_factor, + boolean force_baseline)); +EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); +EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, + boolean suppress)); +EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); +EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); + +/* Main entry points for compression */ +EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, + boolean write_all_tables)); +EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION num_lines)); +EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); + +/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION num_lines)); + +/* Write a special marker. See libjpeg.doc concerning safe usage. */ +EXTERN(void) jpeg_write_marker + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); +/* Same, but piecemeal. */ +EXTERN(void) jpeg_write_m_header + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); +EXTERN(void) jpeg_write_m_byte + JPP((j_compress_ptr cinfo, int val)); + +/* Alternate compression function: just write an abbreviated table file */ +EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); + +/* Decompression startup: read start of JPEG datastream to see what's there */ +EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, + boolean require_image)); +/* Return value is one of: */ +#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ +#define JPEG_HEADER_OK 1 /* Found valid image datastream */ +#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ +/* If you pass require_image = TRUE (normal case), you need not check for + * a TABLES_ONLY return code; an abbreviated file will cause an error exit. + * JPEG_SUSPENDED is only possible if you use a data source module that can + * give a suspension return (the stdio source module doesn't). + */ + +/* Main entry points for decompression */ +EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); +EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, + JSAMPARRAY scanlines, + JDIMENSION max_lines)); +EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); + +/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ +EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, + JSAMPIMAGE data, + JDIMENSION max_lines)); + +/* Additional entry points for buffered-image mode. */ +EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, + int scan_number)); +EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); +EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); +EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); +/* Return value is one of: */ +/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ +#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ +#define JPEG_REACHED_EOI 2 /* Reached end of image */ +#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ +#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ + +/* Precalculate output dimensions for current decompression parameters. */ +EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); + +/* Control saving of COM and APPn markers into marker_list. */ +EXTERN(void) jpeg_save_markers + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); + +/* Install a special processing method for COM or APPn markers. */ +EXTERN(void) jpeg_set_marker_processor + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); + +/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ +EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); +EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays)); +EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, + j_compress_ptr dstinfo)); + +/* If you choose to abort compression or decompression before completing + * jpeg_finish_(de)compress, then you need to clean up to release memory, + * temporary files, etc. You can just call jpeg_destroy_(de)compress + * if you're done with the JPEG object, but if you want to clean it up and + * reuse it, call this: + */ +EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); +EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); + +/* Generic versions of jpeg_abort and jpeg_destroy that work on either + * flavor of JPEG object. These may be more convenient in some places. + */ +EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); +EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); + +/* Default restart-marker-resync procedure for use by data source modules */ +EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, + int desired)); + + +/* These marker codes are exported since applications and data source modules + * are likely to want to use them. + */ + +#define JPEG_RST0 0xD0 /* RST0 marker code */ +#define JPEG_EOI 0xD9 /* EOI marker code */ +#define JPEG_APP0 0xE0 /* APP0 marker code */ +#define JPEG_COM 0xFE /* COM marker code */ + + +/* If we have a brain-damaged compiler that emits warnings (or worse, errors) + * for structure definitions that are never filled in, keep it quiet by + * supplying dummy definitions for the various substructures. + */ + +#ifdef INCOMPLETE_TYPES_BROKEN +#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ +struct jvirt_sarray_control { long dummy; }; +struct jvirt_barray_control { long dummy; }; +struct jpeg_comp_master { long dummy; }; +struct jpeg_c_main_controller { long dummy; }; +struct jpeg_c_prep_controller { long dummy; }; +struct jpeg_c_coef_controller { long dummy; }; +struct jpeg_marker_writer { long dummy; }; +struct jpeg_color_converter { long dummy; }; +struct jpeg_downsampler { long dummy; }; +struct jpeg_forward_dct { long dummy; }; +struct jpeg_entropy_encoder { long dummy; }; +struct jpeg_decomp_master { long dummy; }; +struct jpeg_d_main_controller { long dummy; }; +struct jpeg_d_coef_controller { long dummy; }; +struct jpeg_d_post_controller { long dummy; }; +struct jpeg_input_controller { long dummy; }; +struct jpeg_marker_reader { long dummy; }; +struct jpeg_entropy_decoder { long dummy; }; +struct jpeg_inverse_dct { long dummy; }; +struct jpeg_upsampler { long dummy; }; +struct jpeg_color_deconverter { long dummy; }; +struct jpeg_color_quantizer { long dummy; }; +#endif /* JPEG_INTERNALS */ +#endif /* INCOMPLETE_TYPES_BROKEN */ + + +/* + * The JPEG library modules define JPEG_INTERNALS before including this file. + * The internal structure declarations are read only when that is true. + * Applications using the library should not include jpegint.h, but may wish + * to include jerror.h. + */ + +#ifdef JPEG_INTERNALS +#include "jpegint.h" /* fetch private declarations */ +#include "jerror.h" /* fetch error codes too */ +#endif + +#endif /* JPEGLIB_H */ diff --git a/core/multimedia/opieplayer/libflash/libflash.pro b/core/multimedia/opieplayer/libflash/libflash.pro new file mode 100644 index 0000000..d144f0b --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/libflash.pro @@ -0,0 +1,15 @@ +TEMPLATE = lib +CONFIG += qt warn_on release +HEADERS = libflashplugin.h libflashpluginimpl.h +SOURCES = libflashplugin.cpp libflashpluginimpl.cpp \ + adpcm.cc character.cc flash.cc graphic16.cc matrix.cc script.cc \ + sprite.cc bitmap.cc cxform.cc font.cc graphic24.cc movie.cc \ + shape.cc sqrt.cc button.cc displaylist.cc graphic.cc graphic32.cc \ + program.cc sound.cc text.cc +TARGET = flashplugin +DESTDIR = ../../plugins/codecs +INCLUDEPATH += $(QPEDIR)/include .. +DEPENDPATH += ../$(QPEDIR)/include .. +LIBS += -lqpe +VERSION = 1.0.0 + diff --git a/core/multimedia/opieplayer/libflash/libflashplugin.cpp b/core/multimedia/opieplayer/libflash/libflashplugin.cpp new file mode 100644 index 0000000..538c695 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/libflashplugin.cpp @@ -0,0 +1,223 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "libflashplugin.h" + +#if 0 + +bool LibFlashPlugin::audioReadSamples( short *output, int channel, long samples, int stream ) { +} + + +bool LibFlashPlugin::audioReReadSamples( short *output, int channel, long samples, int stream ) { +} + + +bool LibFlashPlugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) { + samplesRead = samples; +} + + +bool LibFlashPlugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) { +} + + +bool LibFlashPlugin::videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) { +} + + +bool LibFlashPlugin::videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ) { +/* + int format = MPEG3_RGB565; + switch ( color_model ) { + case RGB565: format = MPEG3_RGB565; break; + case RGBA8888: format = MPEG3_RGBA8888; break; + case BGRA8888: format = MPEG3_BGRA8888; break; + } +*/ +} + + +bool LibFlashPlugin::videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ) { +} + + +FlashHandle file; +FlashDisplay *fd; + +#endif + + +LibFlashPlugin::LibFlashPlugin() { + file = NULL; + fd = 0; +} +#include +#include +static int readFile(const char *filename, char **buffer, long *size) +{ + FILE *in; + char *buf; + long length; + + printf("read files\n"); + + in = fopen(filename,"r"); + if (in == 0) { + perror(filename); + return -1; + } + fseek(in,0,SEEK_END); + length = ftell(in); + rewind(in); + buf = (char *)malloc(length); + fread(buf,length,1,in); + fclose(in); + + *size = length; + *buffer = buf; + + return length; +} + +static void showUrl(char *url, char * /*target*/, void * /*client_data*/) { + printf("get url\n"); + printf("GetURL : %s\n", url); +} + +static void getSwf(char *url, int level, void *client_data) { + FlashHandle flashHandle = (FlashHandle) client_data; + char *buffer; + long size; + + printf("get swf\n"); + + printf("LoadMovie: %s @ %d\n", url, level); + if (readFile(url, &buffer, &size) > 0) { + FlashParse(flashHandle, level, buffer, size); + } +} + +bool LibFlashPlugin::open( const QString& fileName ) { + + printf("opening file\n"); + + delete fd; + fd = new FlashDisplay; + fd->pixels = new int[320*240*4]; + fd->width = 200; + fd->bpl = 320*2; + fd->height = 300; + fd->depth = 16; + fd->bpp = 2; + fd->flash_refresh = 25; + fd->clip_x = 0; + fd->clip_y = 0; + fd->clip_width = 0; + fd->clip_height = 0; + + char *buffer; + long size; + int status; + struct FlashInfo fi; + + if (readFile(fileName.latin1(), &buffer, &size) < 0) + exit(2); + + if (!(file = FlashNew())) + exit(1); + + do + status = FlashParse(file, 0, buffer, size); + while (status & FLASH_PARSE_NEED_DATA); + + free(buffer); + FlashGetInfo(file, &fi); + //FlashSettings(flashHandle, PLAYER_LOOP); + FlashGraphicInit(file, fd); + FlashSoundInit(file, "/dev/dsp"); + FlashSetGetUrlMethod(file, showUrl, 0); + FlashSetGetSwfMethod(file, getSwf, (void*)file); + + printf("opened file\n"); +} + +// If decoder doesn't support audio then return 0 here +bool LibFlashPlugin::audioSetSample( long sample, int stream ) { return TRUE; } +long LibFlashPlugin::audioGetSample( int stream ) { return 0; } +//bool LibFlashPlugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) { return TRUE; } +//bool LibFlashPlugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) { return FALSE; } +bool LibFlashPlugin::audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ) { return FALSE; } +//bool LibFlashPlugin::audioReadSamples( short *output, int channel, long samples, int stream ) { return TRUE; } +//bool LibFlashPlugin::audioReReadSamples( short *output, int channel, long samples, int stream ) { return TRUE; } + +// If decoder doesn't support video then return 0 here +int LibFlashPlugin::videoStreams() { return 1; } +int LibFlashPlugin::videoWidth( int stream ) { return 300; } +int LibFlashPlugin::videoHeight( int stream ) { return 200; } +double LibFlashPlugin::videoFrameRate( int stream ) { return 25.0; } +int LibFlashPlugin::videoFrames( int stream ) { return 1000000; } +bool LibFlashPlugin::videoSetFrame( long frame, int stream ) { return TRUE; } +long LibFlashPlugin::videoGetFrame( int stream ) { return 0; } +bool LibFlashPlugin::videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) { return TRUE; } +#include +bool LibFlashPlugin::videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ) { + struct timeval wd; + FlashEvent fe; + +/* + delete fd; + fd = new FlashDisplay; + fd->pixels = output_rows[0]; + fd->width = 300; // out_w; + fd->bpl = 640; // out_w*2; + fd->height = 200;//out_h; + fd->depth = 16; + fd->bpp = 2; + fd->flash_refresh = 50; + fd->clip_x = 0;//in_x; + fd->clip_y = 0;//in_y; + fd->clip_width = 300;//in_w; + fd->clip_height = 200;//in_h; + FlashGraphicInit(file, fd); +*/ + + long cmd = FLASH_WAKEUP; + FlashExec(file, cmd, 0, &wd); + + fe.type = FeRefresh; + cmd = FLASH_EVENT; + FlashExec(file, cmd, &fe, &wd); +/* + for (int i = 0; i < out_h; i++) + memcpy( output_rows[i], (char*)fd->pixels + i*fd->bpl, QMIN( fd->width * fd->bpp, out_w * fd->bpp ) ); +*/ + memcpy( output_rows[0], (char*)fd->pixels, out_w * out_h * 2 ); +} + +bool LibFlashPlugin::videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ) { return TRUE; } + +// Profiling +double LibFlashPlugin::getTime() { return 0.0; } + +// Ignore if these aren't supported +bool LibFlashPlugin::setSMP( int cpus ) { return TRUE; } +bool LibFlashPlugin::setMMX( bool useMMX ) { return TRUE; } + + diff --git a/core/multimedia/opieplayer/libflash/libflashplugin.h b/core/multimedia/opieplayer/libflash/libflashplugin.h new file mode 100644 index 0000000..532bca2 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/libflashplugin.h @@ -0,0 +1,96 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef LIBFLASH_PLUGIN_H +#define LIBFLASH_PLUGIN_H + + +#include +#include +#include "flash.h" +#include "mediaplayerplugininterface.h" + + +class LibFlashPlugin : public MediaPlayerDecoder { + +public: + LibFlashPlugin(); + ~LibFlashPlugin() { close(); } + + const char *pluginName() { return "LibFlashPlugin: " PLUGIN_NAME " " FLASH_VERSION_STRING; } + const char *pluginComment() { return "This is the libflash library: " PLUGIN_NAME " " FLASH_VERSION_STRING; } + double pluginVersion() { return 1.0; } + + bool isFileSupported( const QString& fileName ) { return fileName.right(4) == ".swf"; } + bool open( const QString& fileName ); + bool close() { FlashClose( file ); file = NULL; return TRUE; } + bool isOpen() { return file != NULL; } + const QString &fileInfo() { return strInfo = qApp->translate( "MediaPlayer", "No Information Available", "media plugin text" ); } + + // If decoder doesn't support audio then return 0 here + int audioStreams() { return 1; } + int audioChannels( int /*stream*/ ) { return 2; } + int audioFrequency( int /*stream*/ ) { return 44100; } + int audioSamples( int /*stream*/ ) { return 1000000; } + bool audioSetSample( long sample, int stream ); + long audioGetSample( int stream ); + //bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ); + //bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ); + bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ); + //bool audioReadSamples( short *output, int channel, long samples, int stream ); + //bool audioReReadSamples( short *output, int channel, long samples, int stream ); + + // If decoder doesn't support video then return 0 here + int videoStreams(); + int videoWidth( int stream ); + int videoHeight( int stream ); + double videoFrameRate( int stream ); + int videoFrames( int stream ); + bool videoSetFrame( long frame, int stream ); + long videoGetFrame( int stream ); + bool videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ); + bool videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ); + bool videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ); + + // Profiling + double getTime(); + + // Ignore if these aren't supported + bool setSMP( int cpus ); + bool setMMX( bool useMMX ); + + // Capabilities + bool supportsAudio() { return TRUE; } + bool supportsVideo() { return TRUE; } + bool supportsYUV() { return TRUE; } + bool supportsMMX() { return TRUE; } + bool supportsSMP() { return TRUE; } + bool supportsStereo() { return TRUE; } + bool supportsScaling() { return TRUE; } + +private: + FlashHandle file; + FlashDisplay *fd; + QString strInfo; + +}; + + +#endif + diff --git a/core/multimedia/opieplayer/libflash/libflashpluginimpl.cpp b/core/multimedia/opieplayer/libflash/libflashpluginimpl.cpp new file mode 100644 index 0000000..af2c07e --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/libflashpluginimpl.cpp @@ -0,0 +1,70 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#include "libflashplugin.h" +#include "libflashpluginimpl.h" + + +LibFlashPluginImpl::LibFlashPluginImpl() + : libflashplugin(0), ref(0) +{ +} + + +LibFlashPluginImpl::~LibFlashPluginImpl() +{ + if ( libflashplugin ) + delete libflashplugin; +} + + +MediaPlayerDecoder *LibFlashPluginImpl::decoder() +{ + if ( !libflashplugin ) + libflashplugin = new LibFlashPlugin; + return libflashplugin; +} + + +MediaPlayerEncoder *LibFlashPluginImpl::encoder() +{ + return NULL; +} + + +#ifndef QT_NO_COMPONENT + + +QRESULT LibFlashPluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) ) + *iface = this, (*iface)->addRef(); + return QS_OK; +} + + +Q_EXPORT_INTERFACE() +{ + Q_CREATE_INSTANCE( LibFlashPluginImpl ) +} + + +#endif + diff --git a/core/multimedia/opieplayer/libflash/libflashpluginimpl.h b/core/multimedia/opieplayer/libflash/libflashpluginimpl.h new file mode 100644 index 0000000..b5cc869 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/libflashpluginimpl.h @@ -0,0 +1,53 @@ +/********************************************************************** +** Copyright (C) 2001 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ +#ifndef LIBFLASH_PLUGIN_IMPL_H +#define LIBFLASH_PLUGIN_IMPL_H + + +#include "../mediaplayerplugininterface.h" + + +class LibFlashPlugin; + + +class LibFlashPluginImpl : public MediaPlayerPluginInterface +{ +public: + LibFlashPluginImpl(); + virtual ~LibFlashPluginImpl(); + +#ifndef QT_NO_COMPONENT + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT + +#endif + + virtual MediaPlayerDecoder *decoder(); + virtual MediaPlayerEncoder *encoder(); + +private: + LibFlashPlugin *libflashplugin; + ulong ref; +}; + + +#endif + diff --git a/core/multimedia/opieplayer/libflash/matrix.cc b/core/multimedia/opieplayer/libflash/matrix.cc new file mode 100644 index 0000000..0d8c82c --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/matrix.cc @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "matrix.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +Matrix::Matrix() +{ + a = 1.0; + d = 1.0; + b = c = 0.0; + tx = ty = 0; +} + +Matrix Matrix::operator*(Matrix m) +{ + Matrix mat; + + mat.a = this->a * m.a + this->b * m.c; + mat.b = this->a * m.b + this->b * m.d; + mat.c = this->c * m.a + this->d * m.c; + mat.d = this->c * m.b + this->d * m.d; + + mat.tx = this->getX(m.tx,m.ty); + mat.ty = this->getY(m.tx,m.ty); + + return mat; +} + +Matrix Matrix::invert() +{ + Matrix mat; + float det; + + det = a*d-b*c; + + mat.a = d/det; + mat.b = -b/det; + mat.c = -c/det; + mat.d = a/det; + + mat.tx = - (long)(mat.a * tx + mat.b * ty); + mat.ty = - (long)(mat.c * tx + mat.d * ty); + + return mat; +} diff --git a/core/multimedia/opieplayer/libflash/matrix.h b/core/multimedia/opieplayer/libflash/matrix.h new file mode 100644 index 0000000..83b54c2 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/matrix.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _MATRIX_H_ +#define _MATRIX_H_ + +struct Matrix { + float a,b,c,d; + long tx,ty; +public: + Matrix operator*(Matrix); + Matrix invert(); + Matrix(); + +#ifdef DUMP + void dump(BitStream *bs); +#endif + + inline + long Matrix::getX(long x, long y) + { + return (long) (x*a+y*b+tx); + }; + + inline + long Matrix::getY(long x, long y) + { + return (long) (x*c+y*d+ty); + }; + +}; + +#endif /* _MATRIX_H_ */ diff --git a/core/multimedia/opieplayer/libflash/movie.cc b/core/multimedia/opieplayer/libflash/movie.cc new file mode 100644 index 0000000..349e43b --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/movie.cc @@ -0,0 +1,171 @@ +//////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// +#include "movie.h" + +FlashMovie::FlashMovie() +{ + gd = NULL; + sm = NULL; + getSwf = NULL; + getUrl = NULL; + cursorOnOff = NULL; + buttons_updated = 0; + scheduledTime.tv_sec = -1; + cur_focus = NULL; + lost_over = NULL; + msPerFrame = 0; + + /* mouse handling */ + mouse_active = 0; + mouse_x = -1; + mouse_y = -1; + button_pressed = 0; + refresh = 1; +} + +FlashMovie::~FlashMovie() +{ + CInputScript *n; + + while (main != NULL) { + n = main->next; + delete main; + main = n; + } + + if (gd) delete gd; + if (sm) delete sm; +} + +int +FlashMovie::processMovie(GraphicDevice *gd, SoundMixer *sm) +{ + CInputScript *script; + int wakeUp = 0; + + if (sm && sm->playSounds()) { + wakeUp = 1; + } + for (script = this->main; script != NULL; script = script->next) { + if (script->program == NULL) continue; + if (script->program->nbFrames == 0) continue; + if (script->program->processMovie(gd,sm)) { + wakeUp = 1; + } + } + renderMovie(); + return wakeUp; +} + +int +FlashMovie::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event) +{ + int wakeUp = 0; + + if (sm && sm->playSounds()) { + wakeUp = 1; + } + if (this->main == 0) return 0; + if (this->main->program == 0) return 0; + if (this->main->program->handleEvent(gd, sm, event)) { + wakeUp = 1; + } + renderMovie(); + return wakeUp; +} + +/* current focus bigger and translated if needed */ +void +FlashMovie::renderFocus() +{ + Rect rect,boundary; + Matrix mat; + + if (mouse_active || !cur_focus) return; + + /* rect is the bbox in screen coordinates */ + + // Compute the bounding box in screen coordinates + cur_focus->character->getBoundingBox(&boundary,cur_focus); + mat = (*gd->adjust) * cur_focus->renderMatrix; + transformBoundingBox(&rect, &mat, &boundary, 1); + + gd->drawBox(rect.xmin, rect.ymin, rect.xmax, rect.ymax); +} + +void +FlashMovie::renderMovie() +{ + CInputScript *script,*prev,*next; + Rect clipping; + Matrix identity; + + clipping.reset(); + + // First pass to update the clipping region + for (script = this->main; script != NULL; script = script->next) { + if (script->level == -1) { + clipping.xmin = -32768; + clipping.ymin = -32768; + clipping.xmax = 32767; + clipping.ymax = 32767; + continue; + } + if (script->program == NULL) continue; + if (script->program->dl->bbox.xmin == LONG_MAX) continue; + transformBoundingBox(&clipping, &identity, &script->program->dl->bbox, 0); + script->program->render = 0; + } + + if (clipping.xmin == LONG_MAX) return; + + // Update the clipping region + gd->updateClippingRegion(&clipping); + gd->clearCanvas(); + + // Second pass to render the movie + for (script = this->main; script != NULL; script = script->next) { + if (script->level == -1) continue; + if (script->program == NULL) continue; + script->program->dl->render(gd); + } + renderFocus(); + + // Final pass to delete some movies + script = this->main; + prev = 0; + while (script != NULL) { + if (script->level == -1) { + next = script->next; + if (prev == 0) { + this->main = next; + } else { + prev->next = next; + } + delete script; + script = next; + } else { + prev = script; + script = script->next; + } + } +} diff --git a/core/multimedia/opieplayer/libflash/movie.h b/core/multimedia/opieplayer/libflash/movie.h new file mode 100644 index 0000000..d83ce79 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/movie.h @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _MOVIE_H_ +#define _MOVIE_H_ + +#include "swf.h" + +struct FlashMovie { + /* true if a button has been moved */ + int buttons_updated; + + /* current keyboard focus */ + DisplayListEntry *cur_focus; + + /* mouse state */ + long mouse_active; + long mouse_x; + long mouse_y; + int button_pressed; + + Button *lost_over; + + /* a button can return to a given state after some time */ + FlashEvent scheduledEvent; + struct timeval scheduledTime; + + int refresh; + + CInputScript *main; + long msPerFrame; + GraphicDevice *gd; + SoundMixer *sm; + + void (*getUrl)(char *,char *, void *); + void *getUrlClientData; + + void (*getSwf)(char *url, int level, void *clientData); + void *getSwfClientData; + + void (*cursorOnOff)(int , void *); + void *cursorOnOffClientData; + + FlashMovie(); + ~FlashMovie(); + int processMovie(GraphicDevice *gd, SoundMixer *sm); + int handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event); + void renderMovie(); + void renderFocus(); +}; + +#endif /* _MOVIE_H_ */ diff --git a/core/multimedia/opieplayer/libflash/program.cc b/core/multimedia/opieplayer/libflash/program.cc new file mode 100644 index 0000000..c6e8c0f --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/program.cc @@ -0,0 +1,921 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#define NOTHING 0x0 +#define WAKEUP 0x1 +#define GOTO 0x2 +#define REFRESH 0x4 + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +int debug = 0; + +Program::Program(FlashMovie *movie, long n) +{ + long f; + + this->movie = movie; + + totalFrames = 0; + + dl = new DisplayList(movie); + if (dl == NULL) return; + frames = new Frame[n]; + if (frames == NULL) { + delete dl; + return; + } + + nbFrames = 0; + totalFrames = n; + currentFrame = 0; + loadingFrame = 0; + movieWait = 1; + nextFrame = currentFrame; + for(f = 0; f < n; f++) + { + frames[f].controls = 0; + frames[f].label = NULL; + } + + movieStatus = MoviePlay; + settings = 0; +} + +Program::~Program() +{ + int i; + Control *ctrl, *ctrl1; + + delete dl; + + if (frames != NULL) { + for(i=0;inext; + ctrl->next = NULL; + delete ctrl; + ctrl = ctrl1; + } + } + + delete[] frames; + } +} + +void +Program::validateLoadingFrame() +{ + nbFrames = loadingFrame; + loadingFrame++; + movieWait = 0; +} + +Frame * +Program::getFrames() +{ + return frames; +} + +long +Program::getNbFrames() +{ + return nbFrames; +} + +DisplayList * +Program::getDisplayList() +{ + return dl; +} + +long +Program::getCurrentFrame() +{ + return currentFrame; +} + +void +Program::setCurrentFrame(long n) +{ + currentFrame = n; + nextFrame = n; + //refresh = 1; +} + +void +Program::gotoFrame(GraphicDevice *gd, long frame) +{ + long f; + + //printf("GotoFrame %d (Current = %d)\n", frame, currentFrame); + dl->clearList(); + + for(f=0; f <= frame; f++) { + runFrame(gd, 0, f, 0); + } +} + +long +Program::runFrame(GraphicDevice *gd, SoundMixer *sm, long f, long action) +{ + Control *ctrl; + Character *character; + Matrix *matrix; + Cxform *cxform; + long status = NOTHING; + long update = 0; + char *name; + +#if PRINT&1 + if (action) printf("Prog %x (dl=%x): Frame N° %d/%d\n", this, this->dl, f, nbFrames-1); +#endif + movie->buttons_updated = 0; + + for(ctrl = frames[f].controls; ctrl; ctrl = ctrl->next) + { + switch (ctrl->type) + { + case ctrlPlaceObject: + case ctrlPlaceObject2: + character = 0; + matrix = 0; + cxform = 0; + name = ""; + if (ctrl->flags & placeHasCharacter) { + character = ctrl->character; + } + if (ctrl->flags & placeHasMatrix) { + matrix = &ctrl->matrix; + } + if (ctrl->flags & placeHasColorXform) { + cxform = &ctrl->cxform; + } + if (ctrl->flags & placeHasName) { + name = ctrl->name; + } + if (!ctrl->clipDepth) { // Ignore + dl->placeObject(gd,character, ctrl->depth, matrix, cxform, name); + update = 1; + } + break; + case ctrlRemoveObject: + character = ctrl->character; + + if (!character) break; // Should not happen + + dl->removeObject(gd, character, ctrl->depth); + if (action) { + character->reset(); + update = 1; + } + break; + case ctrlRemoveObject2: + character = dl->removeObject(gd,NULL, ctrl->depth); + if (character && action) { + character->reset(); + update = 1; + } + break; + // Actions + case ctrlDoAction: + if (action) { + status = doAction(gd, ctrl->actionRecords, sm); + } + break; + case ctrlStartSound: + if (action && sm) { + sm->startSound( (Sound *)ctrl->character ); + } + break; + case ctrlStopSound: + if (action && sm) { + sm->stopSounds(); + } + break; + case ctrlBackgroundColor: + if (action) { + if (gd->setBackgroundColor(ctrl->color)) { + dl->bbox.xmin = -32768; + dl->bbox.ymin = -32768; + dl->bbox.xmax = 32768; + dl->bbox.ymax = 32768; + } + } + break; + } + } + if (movie->buttons_updated) { + dl->updateButtons(movie); + } + + if (status & GOTO) { + if (nextFrame < nbFrames) { + gotoFrame(gd,nextFrame); + if (nextFrame != f) + if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame); + update = 1; + } + } + +#if PRINT&1 + if (action) printf("Frame N° %d ready\n", f); +#endif + return update; +} + +long +Program::nestedMovie(GraphicDevice *gd, SoundMixer *sm, Matrix *mat, Cxform *cxform) +{ + if (movieStatus == MoviePlay) { + // Movie Beeing Played + advanceFrame(); + if (currentFrame == 0) { + dl->clearList(); + } + runFrame(gd, sm, currentFrame); + if (nbFrames == 1) { + pauseMovie(); + } + } + + return (movieStatus == MoviePlay); +} + +long +Program::processMovie(GraphicDevice *gd, SoundMixer *sm) +{ + int wakeUp = 0; + +#if PRINT&1 + printf("Prog %x (dl=%x): Current = %d Next = %d Wait = %d Status = %d\n", this, this->dl, currentFrame, nextFrame, movieWait, movieStatus); +#endif + + if (movieStatus == MoviePlay && movieWait == 0) { + // Movie Beeing Played + advanceFrame(); + if (currentFrame == 0) { + dl->clearList(); + } + wakeUp |= runFrame(gd, sm, currentFrame); + wakeUp |= dl->updateSprites(); + if (nextFrame == nbFrames) { + if (nbFrames != totalFrames) { + movieWait = 1; + } else if ((settings & PLAYER_LOOP) == 0) { + pauseMovie(); + } + } + } else { + wakeUp |= dl->updateSprites(); + } + + if (wakeUp) { + render = 1; + } + + return (wakeUp || movieStatus == MoviePlay); +} + +/* timer (ms) -1 = delete timer */ +void setFlashTimer(struct timeval *tv, int time_ms) +{ + if (time_ms == -1) { + tv->tv_sec = -1; + } else { + gettimeofday(tv,0); + + tv->tv_usec += time_ms*1000; + while (tv->tv_usec > 1000000) { + tv->tv_usec -= 1000000; + tv->tv_sec++; + } + } +} + +int checkFlashTimer(struct timeval *tv) +{ + struct timeval now; + + if (tv->tv_sec == -1) return 0; + + gettimeofday(&now,0); + return (now.tv_sec > tv->tv_sec || + (now.tv_sec == tv->tv_sec && now.tv_usec >= tv->tv_usec)); +} + +/* bbox */ +typedef struct { + long x1,y1,x2,y2; +} ButtonBoundingBox; + + +static void button_bbox_func(void *id, long y, long start, long end) +{ + ButtonBoundingBox *h = (ButtonBoundingBox *) id; + + if (y < h->y1) h->y1 = y; + if (y > h->y2) h->y2 = y; + if (start < h->x1) h->x1 = start; + if (end > h->x2) h->x2 = end; +} + +void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e) +{ + ButtonBoundingBox bb; + + bb.x1 = LONG_MAX; + bb.y1 = LONG_MAX; + bb.x2 = LONG_MIN; + bb.y2 = LONG_MIN; + + e->character->getRegion(movie->gd,&e->renderMatrix,&bb,button_bbox_func); + + rect->xmin = bb.x1 / FRAC; + rect->xmax = bb.x2 / FRAC; + rect->ymin = bb.y1; + rect->ymax = bb.y2; +} + +void transform_coords(long *x_ptr,long *y_ptr, long cx, long cy, long dx, long dy) +{ + long x,y,x1,y1; + x = *x_ptr; + y = *y_ptr; + + x -= cx; + y -= cy; + + if (dx < 0) { + /* left */ + x1 = - x; + y1 = y; + } else if (dy < 0) { + /* up */ + y1 = x; + x1 = -y; + } else if (dy > 0) { + /* down */ + y1 = x; + x1 = y; + } else { + /* right */ + x1 = x; + y1 = y; + } + + *x_ptr = x1; + *y_ptr = y1; +} + +typedef struct { + FlashMovie *movie; + DisplayListEntry *emin,*cur_focus; + long dmin; + long w,cx,cy,dx,dy; +} ButtonFocus; + +static int button_focus(void *opaque, Program *prg, DisplayListEntry *e) +{ + ButtonFocus *h=(ButtonFocus *)opaque; + Rect rect; + long d,x,y; + + if (e != h->cur_focus) { + computeBBox(h->movie,&rect,e); + x = (rect.xmin + rect.xmax) / 2; + y = (rect.ymin + rect.ymax) / 2; + + /* transform the coords so that the angular sector is directed to the right */ + transform_coords(&x,&y,h->cx,h->cy,h->dx,h->dy); + + /* inside it ? */ + if ( x >= 0 && + (y - x - h->w) <= 0 && + (y + x + h->w) >= 0) { + d = x*x + y*y; + + if (d < h->dmin) { + h->dmin = d; + h->emin = e; + } + } + } + return 0; +} + +DisplayListEntry *moveFocus(FlashMovie *movie, long dx, long dy, + DisplayListEntry *cur_focus) +{ + Rect cur_rect; + ButtonFocus h; + + h.movie = movie; + h.dx = dx; + h.dy = dy; + + computeBBox(movie,&cur_rect,cur_focus); + /* center */ + h.cx = (cur_rect.xmin + cur_rect.xmax) / 2; + h.cy = (cur_rect.ymin + cur_rect.ymax) / 2; + + /* width/2 of the 45 degrees angular sector */ + if (dy != 0) { + /* for vertical displacement, we have a larger width */ + h.w = (cur_rect.xmax - cur_rect.xmin) / 2; + } else { + /* zero width for horizontal displacement */ + h.w = 0; + } + + /* now we select the nearest button in the angular sector */ + h.dmin = LONG_MAX; + h.emin = NULL; + h.cur_focus = cur_focus; + + exploreButtons(movie, &h, button_focus); + + return h.emin; +} + +static int button_newfocus(void *opaque, Program *prg, DisplayListEntry *e) +{ + * (DisplayListEntry **)opaque = e; + return 2; +} + +static int button_nextfocus(void *opaque, Program *prg, DisplayListEntry *e) +{ + static int found = 0; + DisplayListEntry **focus; + + focus = (DisplayListEntry **)opaque; + if (found) { + *focus = e; + found = 0; + return 2; + } + if (e == *focus) { + found = 1; + } + return 0; +} + + +/* XXX: should not be here (one level upper) */ +long +Program::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *fe) +{ + ActionRecord *action; + Program *prog; + long status = 0; + DisplayListEntry *cur_focus, *new_focus; + long dx,dy; + int refresh; + + refresh = 0; + + switch(fe->type) { + + case FeKeyRelease: + if (movie->mouse_active == 0) { + + if (movie->cur_focus) { + movie->cur_focus->owner->updateBoundingBox(movie->cur_focus); + movie->cur_focus->renderState = stateOver; + movie->cur_focus->owner->updateBoundingBox(movie->cur_focus); + } + } + break; + + case FeKeyPress: + + movie->mouse_active = 0; + + /* find the button which has the focus */ + cur_focus = movie->cur_focus; + + if (fe->key == FeKeyEnter) { + /* selection */ + if (cur_focus) { + /* select the button */ + cur_focus->owner->updateBoundingBox(cur_focus); + cur_focus->renderState = stateDown; + ((Button *)cur_focus->character)->updateButtonState(cur_focus); + cur_focus->owner->updateBoundingBox(cur_focus); + + movie->scheduledEvent.type = FeKeyRelease; + movie->scheduledEvent.key = FeKeyEnter; + + setFlashTimer(&movie->scheduledTime, 250); /* 250 ms down */ + } + } else { + /* displacement */ + + if (cur_focus == NULL) { + /* no current focus : set one */ + exploreButtons(movie, &cur_focus, button_newfocus); + if (cur_focus) { + cur_focus->renderState = stateOver; + ((Button *)cur_focus->character)->updateButtonState(cur_focus); + cur_focus->owner->updateBoundingBox(cur_focus); + } + movie->cur_focus = cur_focus; + } else { + /* move the focus (test) */ + switch(fe->key) { + case FeKeyNext: + /* Next available */ + cur_focus->owner->updateBoundingBox(cur_focus); + cur_focus->renderState = stateUp; + ((Button *)cur_focus->character)->updateButtonState(cur_focus); + cur_focus->owner->updateBoundingBox(cur_focus); + exploreButtons(movie, &cur_focus, button_nextfocus); + if (cur_focus) { + cur_focus->renderState = stateOver; + ((Button *)cur_focus->character)->updateButtonState(cur_focus); + cur_focus->owner->updateBoundingBox(cur_focus); + } + movie->cur_focus = cur_focus; + dx = 0; + dy = 0; + break; + case FeKeyUp: + dx = 0; + dy = -1; + break; + case FeKeyDown: + dx = 0; + dy = 1; + break; + case FeKeyLeft: + dx = -1; + dy = 0; + break; + case FeKeyRight: + dx = 1; + dy = 0; + break; + default: + /* should not happen */ + dx = 0; + dy = 0; + break; + } + + if (dx != 0 || dy != 0) { + + new_focus = moveFocus(movie, dx, dy, cur_focus); + if (new_focus) { + cur_focus->owner->updateBoundingBox(cur_focus); + cur_focus->renderState = stateUp; + ((Button *)cur_focus->character)->updateButtonState(cur_focus); + cur_focus->owner->updateBoundingBox(cur_focus); + + if (computeActions(movie, &prog, &action)) { + status |= prog->doAction(gd, action, sm); + } + + new_focus->renderState = stateOver; + ((Button *)new_focus->character)->updateButtonState(new_focus); + movie->cur_focus = new_focus; + new_focus->owner->updateBoundingBox(new_focus); + } else { + return 0; + } + } + } + if (movie->cur_focus == NULL) return 0; + } + break; + + case FeMouseMove: + movie->mouse_active = 1; + movie->mouse_x = fe->x * FRAC; + movie->mouse_y = fe->y * FRAC; + dl->updateButtons(movie); + break; + + case FeButtonPress: + movie->mouse_active = 1; + movie->button_pressed = 1; + dl->updateButtons(movie); + break; + + case FeButtonRelease: + movie->mouse_active = 1; + movie->button_pressed = 0; + dl->updateButtons(movie); + break; + + default: + return 0; + } + + if (computeActions(movie, &prog, &action)) { + status |= prog->doAction(gd, action, sm); + } + + if (status & REFRESH) { + status |= WAKEUP; + refresh = 1; + } + if (status & GOTO) { + if (nextFrame < nbFrames) { + gotoFrame(gd, nextFrame); + if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame); + refresh = 1; + } + } + + if (refresh) { + dl->updateSprites(); + render = 1; + } + return (refresh || movieStatus == MoviePlay); +} + +long +Program::doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *sm) +{ + long status = NOTHING; + long f; + char *target = ""; + long skip = 0; + + while(action) + { + if (skip) skip--; + else + switch (action->action) + { + case ActionPlaySound: +#if PRINT&2 + printf("Prog %x : PlaySound\n", this); +#endif + if (sm) { + sm->startSound(action->sound); + } + status |= WAKEUP; + break; + case ActionRefresh: +#if PRINT&2 + printf("Prog %x : Refresh\n", this); +#endif + status |= REFRESH; + break; + case ActionGotoFrame: +#if PRINT&2 + printf("Prog %x : GotoFrame %d\n", this, action->frameIndex); +#endif + if (target[0] == 0) { + if (action->frameIndex < nbFrames) { + currentFrame = action->frameIndex; + pauseMovie(); + status |= WAKEUP|GOTO; + } + } + break; + case ActionGetURL: +#if PRINT&2 + printf("Prog %x : GetURL %s target = %s\n", this, action->url, action->target); +#endif + { + int len,level; + len = strlen(action->target); + + if (len > 6 && memcmp(action->target,"_level", 6) == 0) { + level = atoi(action->target + 6); + loadNewSwf(movie, action->url, level); + } else { + if (movie->getUrl) { + movie->getUrl(action->url, action->target, movie->getUrlClientData); + } + } + } + break; + case ActionNextFrame: + nextFrame = currentFrame+1; + movieStatus = MoviePlay; + status |= WAKEUP; + break; + case ActionPrevFrame: + nextFrame = currentFrame-1; + status |= WAKEUP|GOTO; + break; + case ActionPlay: +#if PRINT&2 + printf("Prog %x : Play\n", this); +#endif + if (target[0] == 0) { + movieStatus = MoviePlay; + if ((status & GOTO) == 0) { + if (currentFrame == nextFrame) advanceFrame(); + } + status |= WAKEUP; + } + break; + case ActionStop: +#if PRINT&2 + printf("Prog %x : Stop\n", this); +#endif + if (target[0] == 0) { + movieStatus = MoviePaused; + nextFrame = currentFrame; + } + break; + case ActionToggleQuality: + break; + case ActionStopSounds: + if (sm) { + sm->stopSounds(); + } + break; + case ActionWaitForFrame: + if (action->frameIndex >= nbFrames) { + skip = action->skipCount; + } + break; + case ActionSetTarget: +#if PRINT&2 + printf("Prog %x : SetTarget '%s'\n", this, action->target); +#endif + target = action->target; + break; + case ActionGoToLabel: +#if PRINT&2 + printf("Prog %x : GotoFrame '%s'\n", this, action->frameLabel); +#endif + f = searchFrame(gd, action->frameLabel, target); + if (f >= 0) { + currentFrame = f; + pauseMovie(); + status |= WAKEUP|GOTO; + } else { + status |= REFRESH; + } + break; + } + action = action->next; + } + return status; +} + +void +Program::setCurrentFrameLabel(char *label) +{ + frames[loadingFrame].label = label; +} + +void +Program::rewindMovie() +{ + currentFrame = 0; + nextFrame = 0; +} + +void +Program::pauseMovie() +{ + movieStatus = MoviePaused; + nextFrame = currentFrame; +} + +void +Program::continueMovie() +{ + movieStatus = MoviePlay; +} + +void +Program::nextStepMovie() +{ + if (movieStatus == MoviePaused) { + advanceFrame(); + } +} + +void +Program::advanceFrame() +{ + currentFrame = nextFrame; + nextFrame = currentFrame+1; + if (currentFrame == nbFrames) { + currentFrame = 0; + nextFrame = 0; + movieStatus = MoviePlay; + } +} + +void +Program::addControlInCurrentFrame(Control *ctrl) +{ + Control *c; + + ctrl->next = 0; + if (frames[loadingFrame].controls == 0) { + frames[loadingFrame].controls = ctrl; + } else { + for(c = frames[loadingFrame].controls; c->next; c = c->next); + c->next = ctrl; + } +} + +void +Program::modifySettings(long flags) +{ + settings = flags; +} + +long +Program::searchFrame(GraphicDevice *gd, char *label, char *target) +{ + long f; + DisplayListEntry *e; + Program *prg; + + // Current movie + if (target[0] == 0) { + for(f=0; f < nbFrames; f++) + { + if (frames[f].label && !strcmp(label,frames[f].label)) { + return f; + } + } + } + + // Kludge !!! + for (e = dl->list; e; e = e->next) { + if (e->character->isSprite()) { + prg = ((Sprite *)e->character)->program; + f = prg->searchFrame(gd,label,""); + if (f >= 0 && f < prg->nbFrames) { + prg->dl->updateBoundingBox(e); + prg->gotoFrame(gd, f); + prg->nextFrame = f; + prg->dl->updateBoundingBox(e); + return -1; + } + } + } + + return -1; +} + +void loadNewSwf(FlashMovie *movie, char *url, int level) +{ + CInputScript *s,*prev,**l; + + if (movie->getSwf == NULL) return; + + for(s = movie->main, prev = 0; s != NULL; prev = s, s = s->next) { + if (s->level == level) { + // Mark movie to be deleted + s->level = -1; + break; + } + } + + //printf("Unload movie @ %d\n", level); + + if (*url == 0) return; // Just UnloadMovie + + s = new CInputScript(level); + if (s == NULL) return; + + /* insert it in the right order */ + l = &movie->main; + while (*l != NULL && (*l)->level < level) l = &(*l)->next; + s->next = *l; + *l = s; + + // Notify the external loader of a new movie to load + movie->getSwf(url, level, movie->getSwfClientData); +} diff --git a/core/multimedia/opieplayer/libflash/program.h b/core/multimedia/opieplayer/libflash/program.h new file mode 100644 index 0000000..7672d88 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/program.h @@ -0,0 +1,185 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _PROGRAM_H_ +#define _PROGRAM_H_ + +enum ControlType { + ctrlPlaceObject, + ctrlPlaceObject2, + ctrlRemoveObject, + ctrlRemoveObject2, + ctrlDoAction, + ctrlStartSound, + ctrlStopSound, + ctrlBackgroundColor +}; + +enum PlaceFlags { + placeIsMove = 0x01, + placeHasCharacter = 0x02, + placeHasMatrix = 0x04, + placeHasColorXform = 0x08, + placeHasRatio = 0x10, + placeHasName = 0x20, + placeHasClip = 0x40 +}; + +struct Control { + ControlType type; + + // Place, Remove, Sound + Character *character; + long depth; + + // Place 1&2 + PlaceFlags flags; + Matrix matrix; + Cxform cxform; + long ratio; + long clipDepth; + char *name; + + // BackgroundColor + Color color; + + // DoAction + ActionRecord *actionRecords; + + struct Control *next; + + + // Methods + + void addActionRecord( ActionRecord *ar) + { + ar->next = 0; + + if (actionRecords == 0) { + actionRecords = ar; + } else { + ActionRecord *current; + + for(current = actionRecords; current->next; current = current->next); + + current->next = ar; + } + }; + + Control() + { + actionRecords = 0; + cxform.aa = 1.0; cxform.ab = 0; + cxform.ra = 1.0; cxform.rb = 0; + cxform.ga = 1.0; cxform.gb = 0; + cxform.ba = 1.0; cxform.bb = 0; + ratio = 0; + clipDepth = 0; + name = 0; + }; + + ~Control() + { + ActionRecord *ar,*del; + for(ar = actionRecords; ar;) + { + del = ar; + ar = ar->next; + delete del; + } + if (name) { + free(name); + } + }; +}; + +struct Frame { + char *label; + Control *controls; // Controls for this frame +}; + +enum MovieStatus { + MoviePaused, + MoviePlay +}; + +struct FlashMovie; + +struct Program { + DisplayList *dl; + + Frame *frames; // Array + long nbFrames; // Number of valid frames + long currentFrame; + long loadingFrame; + long totalFrames; // Total expected number of frames + long nextFrame; + int movieWait; // If true freeze movie until next loaded frame + MovieStatus movieStatus; + Sound *currentSound; + long settings; + FlashMovie *movie; + long render; // True if needed to be rendered + + Program(FlashMovie *movie,long n); + ~Program(); + + void rewindMovie(); + void pauseMovie(); + void continueMovie(); + void nextStepMovie(); + void gotoFrame(GraphicDevice *gd, long f); + + long processMovie(GraphicDevice *, SoundMixer *); + long nestedMovie(GraphicDevice *, SoundMixer *, Matrix *, Cxform *); + long runFrame(GraphicDevice *, SoundMixer *, long f, long action=1); + long handleEvent(GraphicDevice *, SoundMixer *, FlashEvent *); + long doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *); + void setCurrentFrameLabel(char *label); + void advanceFrame(); + void addControlInCurrentFrame(Control *ctrl); + void setGetUrlMethod( void (*)(char *, char *, void *), void *); + void modifySettings(long flags); + long searchFrame(GraphicDevice *gd, char *, char *); + void validateLoadingFrame(); + long getCurrentFrame(); + void setCurrentFrame(long); + + Frame *getFrames(); + long getNbFrames(); + + DisplayList *getDisplayList(); + +#ifdef DUMP + void dump(BitStream *bs); +static void dumpActions(BitStream *bs, ActionRecord *actions); +#endif +}; + +DisplayListEntry *findFocus(DisplayList *dl); +void setFlashTimer(struct timeval *tv, int time_ms); +int checkFlashTimer(struct timeval *tv); + +void loadNewSwf(FlashMovie *movie, char *url, int level); + +void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e); + +long processMovie(FlashMovie *movie); + +#endif /* _PROGRAM_H_ */ diff --git a/core/multimedia/opieplayer/libflash/rect.h b/core/multimedia/opieplayer/libflash/rect.h new file mode 100644 index 0000000..cb84eb3 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/rect.h @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _RECT_H_ +#define _RECT_H_ + +struct Rect +{ + long xmin; + long xmax; + long ymin; + long ymax; + + long getWidth() { + return xmax-xmin; + }; + + long getHeight() { + return ymax-ymin; + }; + + void print() { + printf("Xmin = %d Xmax = %d Ymin = %d Ymax = %d\n", + (int)xmin,(int)xmax,(int)ymin,(int)ymax); + }; + + void reset() { + xmin = LONG_MAX; + ymin = LONG_MAX; + xmax = LONG_MIN; + ymax = LONG_MIN; + }; + +#ifdef DUMP + void dump(BitStream *bs); +#endif +}; + +#endif /* _RECT_H_ */ diff --git a/core/multimedia/opieplayer/libflash/script.cc b/core/multimedia/opieplayer/libflash/script.cc new file mode 100644 index 0000000..db65819 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/script.cc @@ -0,0 +1,1988 @@ +#include "swf.h" + +//////////////////////////////////////////////////////////// +// This file is derived from the 'buggy' SWF parser provided +// by Macromedia. +// +// Modifications : Olivier Debon +// + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define printf(fmt,args...) + +////////////////////////////////////////////////////////////////////// +// Inline input script object methods. +////////////////////////////////////////////////////////////////////// + +// +// Inlines to parse a Flash file. +// +inline U8 CInputScript::GetByte(void) +{ + return m_fileBuf[m_filePos++]; +} + +inline U16 CInputScript::GetWord(void) +{ + U8 * s = m_fileBuf + m_filePos; + m_filePos += 2; + return (U16) s[0] | ((U16) s[1] << 8); +} + +inline U32 CInputScript::GetDWord(void) +{ + U8 * s = m_fileBuf + m_filePos; + m_filePos += 4; + return (U32) s[0] | ((U32) s[1] << 8) | ((U32) s[2] << 16) | ((U32) s [3] << 24); +} + + + + +////////////////////////////////////////////////////////////////////// +// Input script object methods. +////////////////////////////////////////////////////////////////////// + +CInputScript::CInputScript(int level) +// Class constructor. +{ + this->level = level; + + // Initialize the input pointer. + m_fileBuf = NULL; + + // Initialize the file information. + m_filePos = 0; + m_fileSize = 0; + m_fileVersion = 0; + + // Initialize the bit position and buffer. + m_bitPos = 0; + m_bitBuf = 0; + + // Initialize the output file. + m_outputFile = NULL; + + // Set to true if we wish to dump all contents long form + m_dumpAll = false; + + // if set to true will dump image guts (i.e. jpeg, zlib, etc. data) + m_dumpGuts = false; + + needHeader = 1; + program = 0; + + outOfMemory = 0; + + next = NULL; + + return; +} + + +CInputScript::~CInputScript(void) +// Class destructor. +{ + // Free the buffer if it is there. + if (m_fileBuf) + { + delete program; + m_fileBuf = NULL; + m_fileSize = 0; + } +} + + +U16 CInputScript::GetTag(void) +{ + // Save the start of the tag. + m_tagStart = m_filePos; + + if (m_actualSize-m_filePos < 2) return notEnoughData; + + // Get the combined code and length of the tag. + U16 code = GetWord(); + + // The length is encoded in the tag. + U32 len = code & 0x3f; + + // Remove the length from the code. + code = code >> 6; + + // Determine if another long word must be read to get the length. + if (len == 0x3f) { + if (m_actualSize-m_filePos < 4) return notEnoughData; + len = (U32) GetDWord(); + } + + // Determine the end position of the tag. + m_tagEnd = m_filePos + (U32) len; + m_tagLen = (U32) len; + + return code; +} + + +void CInputScript::GetRect (Rect * r) +{ + InitBits(); + int nBits = (int) GetBits(5); + r->xmin = GetSBits(nBits); + r->xmax = GetSBits(nBits); + r->ymin = GetSBits(nBits); + r->ymax = GetSBits(nBits); +} + +void CInputScript::GetMatrix(Matrix* mat) +{ + InitBits(); + + // Scale terms + if (GetBits(1)) + { + int nBits = (int) GetBits(5); + mat->a = (float)(GetSBits(nBits))/(float)0x10000; + mat->d = (float)(GetSBits(nBits))/(float)0x10000; + } + else + { + mat->a = mat->d = 1.0; + } + + // Rotate/skew terms + if (GetBits(1)) + { + int nBits = (int)GetBits(5); + mat->c = (float)(GetSBits(nBits))/(float)0x10000; + mat->b = (float)(GetSBits(nBits))/(float)0x10000; + } + else + { + mat->b = mat->c = 0.0; + } + + // Translate terms + int nBits = (int) GetBits(5); + mat->tx = GetSBits(nBits); + mat->ty = GetSBits(nBits); +} + + +void CInputScript::GetCxform(Cxform* cx, BOOL hasAlpha) +{ + int flags; + int nBits; + float aa; long ab; + float ra; long rb; + float ga; long gb; + float ba; long bb; + + InitBits(); + + flags = (int) GetBits(2); + nBits = (int) GetBits(4); + aa = 1.0; ab = 0; + if (flags & 1) + { + ra = (float) GetSBits(nBits)/256.0; + ga = (float) GetSBits(nBits)/256.0; + ba = (float) GetSBits(nBits)/256.0; + if (hasAlpha) aa = (float) GetSBits(nBits)/256.0; + } + else + { + ra = ga = ba = 1.0; + } + if (flags & 2) + { + rb = (S32) GetSBits(nBits); + gb = (S32) GetSBits(nBits); + bb = (S32) GetSBits(nBits); + if (hasAlpha) ab = (S32) GetSBits(nBits); + } + else + { + rb = gb = bb = 0; + } + if (cx) { + cx->aa = aa; + cx->ab = ab; + cx->ra = ra; + cx->rb = rb; + cx->ga = ga; + cx->gb = gb; + cx->ba = ba; + cx->bb = bb; + } +} + + +/* XXX: should allocate string */ +char *CInputScript::GetString(void) +{ + // Point to the string. + char *str = (char *) &m_fileBuf[m_filePos]; + + // Skip over the string. + while (GetByte()); + + return str; +} + +void CInputScript::InitBits(void) +{ + // Reset the bit position and buffer. + m_bitPos = 0; + m_bitBuf = 0; +} + + +S32 CInputScript::GetSBits (S32 n) +// Get n bits from the string with sign extension. +{ + // Get the number as an unsigned value. + S32 v = (S32) GetBits(n); + + // Is the number negative? + if (v & (1L << (n - 1))) + { + // Yes. Extend the sign. + v |= -1L << n; + } + + return v; +} + + +U32 CInputScript::GetBits (S32 n) +// Get n bits from the stream. +{ + U32 v = 0; + + for (;;) + { + S32 s = n - m_bitPos; + if (s > 0) + { + // Consume the entire buffer + v |= m_bitBuf << s; + n -= m_bitPos; + + // Get the next buffer + m_bitBuf = GetByte(); + m_bitPos = 8; + } + else + { + // Consume a portion of the buffer + v |= m_bitBuf >> -s; + m_bitPos -= n; + m_bitBuf &= 0xff >> (8 - m_bitPos); // mask off the consumed bits + return v; + } + } +} + +void CInputScript::ParseFreeCharacter() +{ + U32 tagid = (U32) GetWord(); + + tagid = tagid; + + printf("tagFreeCharacter \ttagid %-5u\n", tagid); +} + + +void CInputScript::ParsePlaceObject() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlPlaceObject; + ctrl->flags = (PlaceFlags)(placeHasMatrix | placeHasCharacter); + + ctrl->character = getCharacter(GetWord()); + ctrl->depth = GetWord(); + + GetMatrix(&(ctrl->matrix)); + + if ( m_filePos < m_tagEnd ) + { + ctrl->flags = (PlaceFlags)(ctrl->flags | placeHasColorXform); + + GetCxform(&ctrl->cxform, false); + } + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParsePlaceObject2() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlPlaceObject2; + + ctrl->flags = (PlaceFlags)GetByte(); + ctrl->depth = GetWord(); + + // Get the tag if specified. + if (ctrl->flags & placeHasCharacter) + { + ctrl->character = getCharacter(GetWord()); + } + + // Get the matrix if specified. + if (ctrl->flags & placeHasMatrix) + { + GetMatrix(&(ctrl->matrix)); + } + + // Get the color transform if specified. + if (ctrl->flags & placeHasColorXform) + { + GetCxform(&ctrl->cxform, true); + } + + // Get the ratio if specified. + if (ctrl->flags & placeHasRatio) + { + ctrl->ratio = GetWord(); + } + + // Get the ratio if specified. + if (ctrl->flags & placeHasName) + { + ctrl->name = strdup(GetString()); + } + + // Get the clipdepth if specified. + if (ctrl->flags & placeHasClip) + { + ctrl->clipDepth = GetWord(); + } + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParseRemoveObject() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlRemoveObject; + ctrl->character = getCharacter(GetWord()); + ctrl->depth = GetWord(); + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParseRemoveObject2() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlRemoveObject2; + ctrl->depth = GetWord(); + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParseSetBackgroundColor() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlBackgroundColor; + ctrl->color.red = GetByte(); + ctrl->color.green = GetByte(); + ctrl->color.blue = GetByte(); + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParseDoAction() +{ + Control *ctrl; + ActionRecord *ar; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlDoAction; + + do { + ar = ParseActionRecord(); + if (ar) { + ctrl->addActionRecord( ar ); + } + if (outOfMemory) { + return; + } + } while (ar); + + program->addControlInCurrentFrame(ctrl); + +} + + +void CInputScript::ParseStartSound() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->character = getCharacter(GetWord()); + ctrl->type = ctrlStartSound; + + program->addControlInCurrentFrame(ctrl); + + if (!m_dumpAll) + return; + + U32 code = GetByte(); + + printf("code %-3u", code); + + if ( code & soundHasInPoint ) + printf(" inpoint %u ", GetDWord()); + if ( code & soundHasOutPoint ) + printf(" oupoint %u", GetDWord()); + if ( code & soundHasLoops ) + printf(" loops %u", GetWord()); + + printf("\n"); + if ( code & soundHasEnvelope ) + { + int points = GetByte(); + + for ( int i = 0; i < points; i++ ) + { + printf("\n"); + printf("mark44 %u", GetDWord()); + printf(" left chanel %u", GetWord()); + printf(" right chanel %u", GetWord()); + printf("\n"); + } + } +} + + +void CInputScript::ParseStopSound() +{ + Control *ctrl; + + ctrl = new Control; + if (ctrl == NULL) { + outOfMemory = 1; + return; + } + ctrl->type = ctrlStopSound; + + program->addControlInCurrentFrame(ctrl); +} + + +void CInputScript::ParseShapeData(int getAlpha, int getStyles) +{ + int shapeRecord = 0; + + if (getStyles) { + // ShapeWithStyle + ParseFillStyle(getAlpha); + ParseLineStyle(getAlpha); + } + + InitBits(); + m_nFillBits = (U16) GetBits(4); + m_nLineBits = (U16) GetBits(4); + + do { + shapeRecord = ParseShapeRecord(getAlpha); + } while (shapeRecord); +} + +int +CInputScript::ParseShapeRecord(long getAlpha) +{ + // Determine if this is an edge. + BOOL isEdge = (BOOL) GetBits(1); + + if (!isEdge) + { + // Handle a state change + U16 flags = (U16) GetBits(5); + + // Are we at the end? + if (flags == 0) + { + // End of shape + return 0; + } + + // Process a move to. + if (flags & flagsMoveTo) + { + U16 nBits = (U16) GetBits(5); + GetSBits(nBits); + GetSBits(nBits); + } + + // Get new fill info. + if (flags & flagsFill0) + { + GetBits(m_nFillBits); + } + if (flags & flagsFill1) + { + GetBits(m_nFillBits); + } + + // Get new line info + if (flags & flagsLine) + { + GetBits(m_nLineBits); + } + + // Check to get a new set of styles for a new shape layer. + if (flags & flagsNewStyles) + { + // Parse the style. + ParseFillStyle(getAlpha); + ParseLineStyle(getAlpha); + + InitBits(); // Bug ! + + // Reset. + m_nFillBits = (U16) GetBits(4); + m_nLineBits = (U16) GetBits(4); + } + + return flags & flagsEndShape ? 0 : 1; + } + else + { + if (GetBits(1)) + { + // Handle a line + U16 nBits = (U16) GetBits(4) + 2; // nBits is biased by 2 + + // Save the deltas + if (GetBits(1)) + { + // Handle a general line. + GetSBits(nBits); + GetSBits(nBits); + } + else + { + // Handle a vert or horiz line. + GetBits(1); + GetSBits(nBits); + } + } + else + { + // Handle a curve + U16 nBits = (U16) GetBits(4) + 2; // nBits is biased by 2 + + // Get the control + GetSBits(nBits); + GetSBits(nBits); + + // Get the anchor + GetSBits(nBits); + GetSBits(nBits); + } + + return 1; + } +} + + +void CInputScript::ParseFillStyle(long getAlpha) + // +{ + U16 i = 0; + FillType type; + Matrix matrix; + + // Get the number of fills. + U16 nFills = GetByte(); + + // Do we have a larger number? + if (nFills == 255) + { + // Get the larger number. + nFills = GetWord(); + } + + // Get each of the fill style. + for (i = 0; i < nFills; i++) + { + U16 fillStyle = GetByte(); + + type = (FillType) fillStyle; + + printf("fillstyle: type=%d\n",defs[i].type); + if (fillStyle & 0x10) + { + U16 nbGradients; + + type = (FillType) (fillStyle & 0x12); + + // Get the gradient matrix. + GetMatrix(&matrix); + + // Get the number of colors. + nbGradients = GetByte(); + + // Get each of the colors. + for (U16 j = 0; j < nbGradients; j++) + { + GetByte(); + GetByte(); + GetByte(); + GetByte(); + if (getAlpha) { + GetByte(); + } + } + } + else if (fillStyle & 0x40) + { + type = (FillType) (fillStyle & 0x41); + + // Get the bitmapId + GetWord(); + + // Get the bitmap matrix. + GetMatrix(&matrix); + } + else + { + type = (FillType) 0; + + // A solid color + GetByte(); + GetByte(); + GetByte(); + if (getAlpha) { + GetByte(); + } + + printf("fillstyle: %x %x %x %x\n", + defs[i].color.red, + defs[i].color.green, + defs[i].color.blue, + defs[i].color.alpha); + } + } +} + +void CInputScript::ParseLineStyle(long getAlpha) +{ + long i; + + // Get the number of lines. + U16 nLines = GetByte(); + + // Do we have a larger number? + if (nLines == 255) + { + // Get the larger number. + nLines = GetWord(); + } + + // Get each of the line styles. + for (i = 0; i < nLines; i++) + { + GetWord(); + GetByte(); + GetByte(); + GetByte(); + if (getAlpha) { + GetByte(); + } + } +} + + +void CInputScript::ParseDefineShape(int level) +{ + Shape *shape; + Rect rect; + U32 tagid; + + tagid = (U32) GetWord(); + shape = new Shape(tagid,level); + if (shape == NULL) { + outOfMemory = 1; + return; + } + shape->dict = this; + + // Get the frame information. + GetRect(&rect); + + shape->setBoundingBox(rect); + + shape->file_ptr = (unsigned char*)malloc(m_tagEnd-m_filePos); + if (shape->file_ptr == NULL) { + outOfMemory = 1; + delete shape; + return; + } + memcpy((void*)shape->file_ptr,(void*)&m_fileBuf[m_filePos], m_tagEnd-m_filePos); + + shape->getStyles = 1; + shape->getAlpha = (level == 3); + + ParseShapeData(level == 3, 1); + + addCharacter(shape); +} + +void CInputScript::S_DumpImageGuts() +{ +#if 0 + U32 lfCount = 0; + printf("----- dumping image details -----"); + while (m_filePos < m_tagEnd) + { + if ((lfCount % 16) == 0) + { + fprintf(stdout, "\n"); + } + lfCount += 1; + fprintf(stdout, "%02x ", GetByte()); + } + fprintf(stdout, "\n"); +#endif +} + +void CInputScript::ParseDefineBits() +{ + Bitmap *bitmap; + U32 tagid = (U32) GetWord(); + int status; + + bitmap = new Bitmap(tagid,1); + if (bitmap == NULL) { + outOfMemory = 1; + return; + } + + status = bitmap->buildFromJpegAbbreviatedData(&m_fileBuf[m_filePos]); + + if (status < 0) { + fprintf(stderr,"Unable to read JPEG data\n"); + delete bitmap; + return; + } + + addCharacter(bitmap); +} + + +void CInputScript::ParseDefineBitsJPEG2() +{ + Bitmap *bitmap; + U32 tagid = (U32) GetWord(); + int status; + + bitmap = new Bitmap(tagid,2); + if (bitmap == NULL) { + outOfMemory = 1; + return; + } + + status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 0, 0); + + if (status < 0) { + fprintf(stderr,"Unable to read JPEG data\n"); + delete bitmap; + return; + } + + addCharacter(bitmap); +} + +void CInputScript::ParseDefineBitsJPEG3() +{ + Bitmap *bitmap; + U32 tagid = (U32) GetWord(); + int status; + long offset; + + printf("tagDefineBitsJPEG3 \ttagid %-5u\n", tagid); + + bitmap = new Bitmap(tagid,3); + if (bitmap == NULL) { + outOfMemory = 1; + return; + } + + offset = GetDWord(); // Not in the specs !!!! + + status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 1, offset); + if (status < 0) { + fprintf(stderr,"Unable to read JPEG data\n"); + delete bitmap; + return; + } + + addCharacter(bitmap); +} + + +void CInputScript::ParseDefineBitsLossless(int level) +{ + Bitmap *bitmap; + U32 tagid = (U32) GetWord(); + int status; + int tableSize; + + bitmap = new Bitmap(tagid,0); + if (bitmap == NULL) { + outOfMemory = 1; + return; + } + + int format = GetByte(); + int width = GetWord(); + int height = GetWord(); + + tableSize = 0; + + if (format == 3) { + tableSize = GetByte(); + } + + status = bitmap->buildFromZlibData(&m_fileBuf[m_filePos], width, height, format, tableSize, level == 2); + + if (status < 0) { + fprintf(stderr,"Unable to read ZLIB data\n"); + delete bitmap; + return; + } + + addCharacter(bitmap); +} + +void CInputScript::ParseJPEGTables() +{ + Bitmap::readJpegTables(&m_fileBuf[m_filePos]); +} + + +ButtonRecord * CInputScript::ParseButtonRecord(long getCxform) +{ + U16 state; + ButtonRecord *br; + long tagid; + Matrix matrix; + long layer; + Cxform *cxform; + + state = (U16) GetByte(); + + if (state == 0) return 0; + + br = new ButtonRecord; + if (br == NULL) { + outOfMemory = 1; + return 0; + } + + tagid = GetWord(); + layer = GetWord(); + GetMatrix(&matrix); + + if (br) { + br->state = (ButtonState) state; + br->character = getCharacter(tagid); + br->layer = layer; + br->cxform = 0; + br->buttonMatrix = matrix; + } + + if (getCxform) { + cxform = new Cxform; + GetCxform(cxform, true); + if (br) { + br->cxform = cxform; + if (cxform == NULL) { + outOfMemory = 1; + } + } + } + + return br; +} + +ActionRecord * CInputScript::ParseActionRecord() +{ + U8 action; + U16 length = 0; + char *url, *target, *label; + long frameIndex, skipCount; + ActionRecord *ar; + + action = GetByte(); + if (action == 0) return 0; + + ar = new ActionRecord; + if (ar == NULL) { + outOfMemory = 1; + return 0; + } + + ar->action = (Action)action; + + if (action & 0x80) { + length = GetWord(); + } + + switch (action) { + case ActionGotoFrame: + frameIndex = GetWord(); + if (ar) { + ar->frameIndex = frameIndex; + } + break; + case ActionGetURL: + url = GetString(); + target = GetString(); + if (ar) { + ar->url = strdup(url); + ar->target = strdup(target); + } + break; + case ActionWaitForFrame: + frameIndex = GetWord(); + skipCount = GetByte(); + if (ar) { + ar->frameIndex = frameIndex; + ar->skipCount = skipCount; + } + break; + case ActionSetTarget: + target = strdup(GetString()); + if (ar) { + ar->target = target; + } + break; + case ActionGoToLabel: + label = GetString(); + if (ar) { + ar->frameLabel = strdup(label); + } + break; + default: + while (length--) { + GetByte(); + } + break; + } + + return ar; +} + +void CInputScript::ParseDefineButton() +{ + Button *button; + ButtonRecord *buttonRecord; + ActionRecord *actionRecord; + + U32 tagid = (U32) GetWord(); + + button = new Button(tagid); + if (button == NULL) { + outOfMemory = 1; + return; + } + + do { + buttonRecord = ParseButtonRecord(); + if (buttonRecord) { + button->addButtonRecord( buttonRecord ); + } + if (outOfMemory) { + return; + } + } while (buttonRecord); + + do { + actionRecord = ParseActionRecord(); + if (actionRecord) { + button->addActionRecord( actionRecord ); + } + if (outOfMemory) { + return; + } + } while (actionRecord); + + addCharacter(button); +} + + +void CInputScript::ParseDefineButton2() +{ + Button *button; + ButtonRecord *buttonRecord; + ActionRecord *actionRecord; + U16 transition; + U16 offset; + U8 menu; + + U32 tagid = (U32) GetWord(); + + button = new Button(tagid); + + if (button == NULL) { + outOfMemory = 1; + return; + } + + menu = GetByte(); + + offset = GetWord(); + + do { + buttonRecord = ParseButtonRecord(true); + if (buttonRecord) { + button->addButtonRecord( buttonRecord ); + } + if (outOfMemory) { + return; + } + } while (buttonRecord); + + while (offset) { + offset = GetWord(); + + transition = GetWord(); + + do { + actionRecord = ParseActionRecord(); + if (actionRecord) { + button->addActionRecord( actionRecord ); + } + if (outOfMemory) { + return; + } + } while (actionRecord); + + button->addCondition( transition ); + } + + addCharacter(button); +} + + +void CInputScript::ParseDefineFont() +{ + SwfFont *font = 0; + U32 tagid = (U32) GetWord(); + long start; + long nb,n; + long offset; + long *offsetTable = 0; + Shape *shapes = 0; + + font = new SwfFont(tagid); + if (font == NULL) { + outOfMemory = 1; + return; + } + start = m_filePos; + + offset = GetWord(); + nb = offset/2; + offsetTable = new long[nb]; + if (offsetTable == NULL) { + goto memory_error; + } + offsetTable[0] = offset; + + for(n=1; nsetFontShapeTable(shapes,nb); + + delete[] offsetTable; + + addCharacter(font); + return; + +memory_error: + outOfMemory = 1; + if (offsetTable) delete offsetTable; + if (font) delete font; + if (shapes) delete[] shapes; +} + + +void CInputScript::ParseDefineMorphShape() +{ + U32 tagid = (U32) GetWord(); + + tagid = tagid; + printf("tagDefineMorphShape \ttagid %-5u\n", tagid); +} + +void CInputScript::ParseDefineFontInfo() +{ + SwfFont *font; + U32 tagid = (U32) GetWord(); + long nameLen; + char *name; + long n,nb; + FontFlags flags; + long *lut; + + font = (SwfFont *)getCharacter(tagid); + + if (font == NULL) { + outOfMemory = 1; + return; + } + + nameLen = GetByte(); + name = new char[nameLen+1]; + if (name == NULL) { + outOfMemory = 1; + return; + } + for(n=0; n < nameLen; n++) + { + name[n] = GetByte(); + } + name[n]=0; + + font->setFontName(name); + + delete name; + + flags = (FontFlags)GetByte(); + + font->setFontFlags(flags); + + nb = font->getNbGlyphs(); + + lut = new long[nb]; + if (lut == NULL) { + outOfMemory = 1; + delete font; + return; + } + + for(n=0; n < nb; n++) + { + if (flags & fontWideCodes) { + lut[n] = GetWord(); + } else { + lut[n] = GetByte(); + } + } + + font->setFontLookUpTable(lut); +} + + + + + +void CInputScript::ParseDefineFont2() +{ + int n; + U32 tagid = (U32) GetWord(); + FontFlags flags; + char *name; + long nameLen; + long fontGlyphCount; + long *offsetTable = NULL; + Shape *shapes = NULL; + long start; + SwfFont *font; + long *lut = NULL; + + font = new SwfFont(tagid); + if (font == NULL) { + goto memory_error; + } + + flags = (FontFlags)GetWord(); + + font->setFontFlags(flags); + + nameLen = GetByte(); + name = new char[nameLen+1]; + if (name == NULL) { + goto memory_error; + } + for(n=0; n < nameLen; n++) + { + name[n] = GetByte(); + } + name[n]=0; + + font->setFontName(name); + + delete name; + + fontGlyphCount = GetWord(); + + start = m_filePos; + + offsetTable = new long[fontGlyphCount]; + if (offsetTable == NULL) { + goto memory_error; + } + for (n=0; nsetFontShapeTable(shapes,fontGlyphCount); + + lut = new long[fontGlyphCount]; + if (lut == NULL) { + goto memory_error; + } + + for(n=0; n < fontGlyphCount; n++) + { + if (flags & 4) { + lut[n] = GetWord(); + } else { + lut[n] = GetByte(); + } + } + + font->setFontLookUpTable(lut); + + delete offsetTable; + + addCharacter(font); + + // This is an incomplete parsing + return; + +memory_error: + outOfMemory = 1; + if (font) delete font; + if (offsetTable) delete offsetTable; + if (lut) delete lut; + if (shapes) delete[] shapes; +} + +TextRecord * CInputScript::ParseTextRecord(int hasAlpha) +{ + TextRecord *tr; + TextFlags flags; + + flags = (TextFlags) GetByte(); + if (flags == 0) return 0; + + tr = new TextRecord; + if (tr == NULL) { + outOfMemory = 1; + return 0; + } + + tr->flags = flags; + + if (flags & isTextControl) { + if (flags & textHasFont) { + long fontId; + + fontId = GetWord(); + tr->font = (SwfFont *)getCharacter(fontId); + } + if (flags & textHasColor) { + tr->color.red = GetByte(); + tr->color.green = GetByte(); + tr->color.blue = GetByte(); + if (hasAlpha) { + tr->color.alpha = GetByte(); + } else { + tr->color.alpha = ALPHA_OPAQUE; + } + } + if (flags & textHasXOffset) { + tr->xOffset = GetWord(); + } + if (flags & textHasYOffset) { + tr->yOffset = GetWord(); + } + if (flags & textHasFont) { + tr->fontHeight = GetWord(); + } + tr->nbGlyphs = GetByte(); + } else { + tr->flags = (TextFlags)0; + tr->nbGlyphs = (long)flags; + } + + tr->glyphs = new Glyph[ tr->nbGlyphs ]; + if (tr->glyphs == NULL) { + outOfMemory = 1; + delete tr; + return 0; + } + + InitBits(); + for (int g = 0; g < tr->nbGlyphs; g++) + { + tr->glyphs[g].index = GetBits(m_nGlyphBits); + tr->glyphs[g].xAdvance = GetBits(m_nAdvanceBits); + } + + return tr; +} + +void CInputScript::ParseDefineText(int hasAlpha) +{ + Text *text; + TextRecord *textRecord; + Matrix m; + Rect rect; + U32 tagid = (U32) GetWord(); + + text = new Text(tagid); + if (text == NULL) { + outOfMemory = 1; + return; + } + + GetRect(&rect); + text->setTextBoundary(rect); + + GetMatrix(&m); + text->setTextMatrix(m); + + m_nGlyphBits = GetByte(); + m_nAdvanceBits = GetByte(); + + do { + textRecord = ParseTextRecord(hasAlpha); + if (textRecord) { + text->addTextRecord( textRecord ); + } + if (outOfMemory) { + delete text; + return; + } + if (m_filePos >= m_tagEnd) break; + } while (textRecord); + + addCharacter(text); +} + + +void CInputScript::ParseDefineSound() +{ + Sound *sound; + U32 tagid = (U32) GetWord(); + long nbSamples; + long flags; + char *buffer; + + sound = new Sound(tagid); + + flags = GetByte(); + sound->setSoundFlags(flags); + + nbSamples = GetDWord(); + buffer = sound->setNbSamples(nbSamples); + if (buffer == NULL) { + outOfMemory = 1; + delete sound; + return; + } + + if (flags & soundIsADPCMCompressed) { + Adpcm *adpcm; + + adpcm = new Adpcm( &m_fileBuf[m_filePos] , flags & soundIsStereo ); + + adpcm->Decompress((short *)buffer, nbSamples); + + delete adpcm; + } else { + memcpy(buffer, &m_fileBuf[m_filePos], m_tagLen-5); + } + + addCharacter(sound); +} + + +void CInputScript::ParseDefineButtonSound() +{ + U32 tagid = (U32) GetWord(); + Button *button; + + tagid = tagid; + + printf("tagDefineButtonSound \ttagid %-5u\n", tagid); + + button = (Button *)getCharacter(tagid); + + if (button == 0) { + printf(" Couldn't find Button id %d\n", tagid); + return; + } + + // step through for button states + for (int i = 0; i < 4; i++) + { + Sound *sound; + U32 soundTag = GetWord(); + + sound = (Sound *)getCharacter(soundTag); + + if (sound) { + button->setButtonSound(sound,i); + } else if (soundTag) { + printf(" Couldn't find Sound id %d\n", soundTag); + } + + switch (i) + { + case 0: + printf("upState \ttagid %-5u\n", soundTag); + break; + case 1: + printf("overState \ttagid %-5u\n", soundTag); + break; + case 2: + printf("downState \ttagid %-5u\n", soundTag); + break; + } + + if (soundTag) + { + U32 code = GetByte(); + printf("sound code %u", code); + + if ( code & soundHasInPoint ) + printf(" inpoint %u", GetDWord()); + if ( code & soundHasOutPoint ) + printf(" outpoint %u", GetDWord()); + if ( code & soundHasLoops ) + printf(" loops %u", GetWord()); + + printf("\n"); + if ( code & soundHasEnvelope ) + { + int points = GetByte(); + + for ( int p = 0; p < points; p++ ) + { + printf("\n"); + printf("mark44 %u", GetDWord()); + printf(" left chanel %u", GetWord()); + printf(" right chanel %u", GetWord()); + printf("\n"); + } + } + } + if (m_filePos == m_tagEnd) break; + } +} + +void CInputScript::ParseSoundStreamHead() +{ + int mixFormat = GetByte(); + + // The stream settings + int format = GetByte(); + int nSamples = GetWord(); + + mixFormat = mixFormat; + format = format; + nSamples = nSamples; + + printf("tagSoundStreamHead \tmixFrmt %-3u frmt %-3u nSamples %-5u\n", mixFormat, format, nSamples); +} + +void CInputScript::ParseSoundStreamHead2() +{ + int mixFormat = GetByte(); + + // The stream settings + int format = GetByte(); + int nSamples = GetWord(); + + mixFormat = mixFormat; + format = format; + nSamples = nSamples; + + //printf("tagSoundStreamHead2 \tmixFormat %-3u format %-3u nSamples %-5u\n", mixFormat, format, nSamples); +} + +void CInputScript::ParseSoundStreamBlock() +{ + printf("tagSoundStreamBlock\n"); +} + +void CInputScript::ParseDefineButtonCxform() +{ + ButtonRecord *br; + Button *button; + U32 tagid = (U32) GetWord(); + + button = (Button *)getCharacter(tagid); + + for (br = button->getButtonRecords(); br; br = br->next) + { + br->cxform = new Cxform; + GetCxform(br->cxform, false); + } +} + +void CInputScript::ParseNameCharacter() +{ + U32 tagid = (U32) GetWord(); + char *label = strdup(GetString()); + + nameCharacter(tagid, label); +} + + +void CInputScript::ParseFrameLabel() +{ + char *label = strdup(GetString()); + program->setCurrentFrameLabel(label); +} + + +void CInputScript::ParseDefineMouseTarget() +{ + printf("tagDefineMouseTarget\n"); +} + + +void CInputScript::ParseDefineSprite() +{ + Sprite *sprite; + Program *prg; + int status; + + U32 tagid = (U32) GetWord(); + U32 frameCount = (U32) GetWord(); + + if (frameCount == 0) return; + + printf("tagDefineSprite \ttagid %-5u \tframe count %-5u\n", tagid, frameCount); + + sprite = new Sprite(program->movie, tagid, frameCount); + if (sprite == NULL) { + outOfMemory = 1; + return; + } + if (sprite->getProgram() == NULL) { + delete sprite; + outOfMemory = 1; + return; + } + + prg = sprite->getProgram(); + + // Set current program + program = prg; + + ParseTags(&status); + + if (outOfMemory) { + delete sprite; + return; + } + + addCharacter(sprite); +} + + +void CInputScript::ParseUnknown(long code, long len) +{ + printf("Unknown Tag : %d - Length = %d\n", code, len); +} + + +void +CInputScript::ParseTags(int *status) + // Parses the tags within the file. +{ + + // Initialize the end of frame flag. + BOOL atEnd = false; + + // Loop through each tag. + while (!atEnd) + { + U32 here; + + // Get the current tag. + U16 code = GetTag(); + + if (code == notEnoughData) { + m_filePos = m_tagStart; + *status |= FLASH_PARSE_NEED_DATA; + return; + } + + //printf("Code %d, tagLen %8u \n", code, m_tagLen); + + here = m_filePos; + + // Get the tag ending position. + U32 tagEnd = m_tagEnd; + + if (m_tagEnd > m_actualSize) { + m_filePos = m_tagStart; + *status |= FLASH_PARSE_NEED_DATA; + return; + } + + switch (code) + { + case stagProtect: + break; + + case stagEnd: + + // We reached the end of the file. + atEnd = true; + + printf("End of Movie\n"); + + break; + + case stagShowFrame: + + // Validate frame + program->validateLoadingFrame(); + *status |= FLASH_PARSE_WAKEUP; + + break; + + case stagFreeCharacter: + ParseFreeCharacter(); + break; + + case stagPlaceObject: + ParsePlaceObject(); + break; + + case stagPlaceObject2: + ParsePlaceObject2(); + break; + + case stagRemoveObject: + ParseRemoveObject(); + break; + + case stagRemoveObject2: + ParseRemoveObject2(); + break; + + case stagSetBackgroundColor: + ParseSetBackgroundColor(); + break; + + case stagDoAction: + ParseDoAction(); + break; + + case stagStartSound: + ParseStartSound(); + break; + + case stagStopSound: + ParseStopSound(); + break; + + case stagDefineShape: + ParseDefineShape(1); + break; + + case stagDefineShape2: + ParseDefineShape(2); + break; + + case stagDefineShape3: + ParseDefineShape(3); + break; + + case stagDefineBits: + ParseDefineBits(); + break; + + case stagDefineBitsJPEG2: + ParseDefineBitsJPEG2(); + break; + + case stagDefineBitsJPEG3: + ParseDefineBitsJPEG3(); + break; + + case stagDefineBitsLossless: + ParseDefineBitsLossless(1); + break; + + case stagDefineBitsLossless2: + ParseDefineBitsLossless(2); + break; + + case stagJPEGTables: + ParseJPEGTables(); + break; + + case stagDefineButton: + ParseDefineButton(); + break; + + case stagDefineButton2: + ParseDefineButton2(); + break; + + case stagDefineFont: + ParseDefineFont(); + break; + + case stagDefineMorphShape: + ParseDefineMorphShape(); + break; + + case stagDefineFontInfo: + ParseDefineFontInfo(); + break; + + case stagDefineText: + ParseDefineText(0); + break; + + case stagDefineText2: + ParseDefineText(1); + break; + + case stagDefineSound: + ParseDefineSound(); + break; + + case stagDefineButtonSound: + ParseDefineButtonSound(); + break; + + case stagSoundStreamHead: + ParseSoundStreamHead(); + break; + + case stagSoundStreamHead2: + ParseSoundStreamHead2(); + break; + + case stagSoundStreamBlock: + ParseSoundStreamBlock(); + break; + + case stagDefineButtonCxform: + ParseDefineButtonCxform(); + break; + + case stagDefineSprite: + Program *save; + + save = program; + ParseDefineSprite(); + program->rewindMovie(); + program = save; + break; + + case stagNameCharacter: + ParseNameCharacter(); + break; + + case stagFrameLabel: + ParseFrameLabel(); + break; + + case stagDefineFont2: + ParseDefineFont2(); + break; + + default: + ParseUnknown(code, m_tagLen); + break; + } + + //printf("Bytes read = %d\n", m_filePos-here); + + // Increment the past the tag. + m_filePos = tagEnd; + + if (outOfMemory) { + fprintf(stderr,"Flash: Out of memory\n"); + *status |= FLASH_PARSE_OOM; + return; + } + } + + program->validateLoadingFrame(); + *status |= FLASH_PARSE_EOM; +} + +int +CInputScript::ParseData(FlashMovie *movie, char * data, long size) +{ + int status = FLASH_PARSE_ERROR; + + m_fileBuf = (unsigned char *)data; + m_actualSize = size; + + if (needHeader) { + + // Do we have sufficient data to read the header ? + if (size < 21) { + return FLASH_PARSE_NEED_DATA; // No, need more data + } + + needHeader = 0; // Yes + + U8 fileHdr[8]; + + memcpy(fileHdr,data,8); + + // Verify the header and get the file size. + if (fileHdr[0] != 'F' || fileHdr[1] != 'W' || fileHdr[2] != 'S' ) + { + //fprintf(stderr, "Not a Flash File.\n"); + return FLASH_PARSE_ERROR; // Error + } + else + { + // Get the file version. + m_fileVersion = (U16) fileHdr[3]; + } + + // Get the file size. + m_fileSize = (U32) fileHdr[4] + | ((U32) fileHdr[5] << 8) + | ((U32) fileHdr[6] << 16) + | ((U32) fileHdr[7] << 24); + + // Verify the minimum length of a Flash file. + if (m_fileSize < 21) + { + //printf("ERROR: File size is too short\n"); + return FLASH_PARSE_ERROR; // Error + } + + // Set the file position past the header and size information. + m_filePos = 8; + + // Get the frame information. + GetRect(&frameRect); + + frameRate = GetWord() >> 8; + + frameCount = GetWord(); + + program = new Program(movie, frameCount); + + if (program == NULL || program->totalFrames == 0) { + return FLASH_PARSE_ERROR; + } + + status |= FLASH_PARSE_START; + } + + ParseTags(&status); + + return status; +} + + diff --git a/core/multimedia/opieplayer/libflash/script.h b/core/multimedia/opieplayer/libflash/script.h new file mode 100644 index 0000000..a41c47e --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/script.h @@ -0,0 +1,144 @@ +#ifndef _SCRIPT_H_ +#define _SCRIPT_H_ + +// SWF file parser. +// +////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////// +// Input script object definition. +////////////////////////////////////////////////////////////////////// + +// An input script object. This object represents a script created from +// an external file that is meant to be inserted into an output script. +struct CInputScript : public Dict +{ + int level; + struct CInputScript *next; + + Program *program; // Current parsed program + + // Memory fences + int outOfMemory; + + //Flash info + long frameRate; + long frameCount; + Rect frameRect; + + // Pointer to file contents buffer. + U8 *m_fileBuf; + + // File state information. + U32 m_filePos; + U32 m_fileSize; + U32 m_actualSize; + U32 m_fileStart; + U16 m_fileVersion; + + int needHeader; + + // Bit Handling + S32 m_bitPos; + U32 m_bitBuf; + + // Tag parsing information. + U32 m_tagStart; + U32 m_tagEnd; + U32 m_tagLen; + + // Parsing information. + S32 m_nFillBits; + S32 m_nLineBits; + S32 m_nGlyphBits; + S32 m_nAdvanceBits; + + // Set to true if we wish to dump all contents long form + U32 m_dumpAll; + + // if set to true will dump image guts (i.e. jpeg, zlib, etc. data) + U32 m_dumpGuts; + + // Handle to output file. + FILE *m_outputFile; + + // Constructor/destructor. + CInputScript(int level = 0); + ~CInputScript(); + + // Tag scanning methods. + U16 GetTag(void); + U8 GetByte(void); + U16 GetWord(void); + U32 GetDWord(void); + void GetRect(Rect *r); + void GetMatrix(Matrix *matrix); + + void GetCxform(Cxform *cxform, BOOL hasAlpha); + char *GetString(void); + + // Routines for reading arbitrary sized bit fields from the stream. + // Always call start bits before gettings bits and do not intermix + // these calls with GetByte, etc... + void InitBits(); + S32 GetSBits(S32 n); + U32 GetBits(S32 n); + + // Tag subcomponent parsing methods + void ParseFillStyle(long getAlpha = 0); + void ParseLineStyle(long getAlpha = 0); + int ParseShapeRecord(long getAlpha = 0); + ButtonRecord * ParseButtonRecord(long getCxform = 0); + ActionRecord * ParseActionRecord(); + TextRecord * ParseTextRecord(int hasAlpha = 0); + void ParseShapeData(int getAlpha, int getStyles); + + // Parsing methods. + void ParseEnd(); // 00: stagEnd + void ParseShowFrame(U32 frame, U32 offset); // 01: stagShowFrame + void ParseDefineShape(int level); // 02: stagDefineShape + void ParseFreeCharacter(); // 03: stagFreeCharacter + void ParsePlaceObject(); // 04: stagPlaceObject + void ParseRemoveObject(); // 05: stagRemoveObject + void ParseDefineBits(); // 06: stagDefineBits + void ParseDefineButton(); //x 07: stagDefineButton + void ParseJPEGTables(); // 08: stagJPEGTables + void ParseSetBackgroundColor(); // 09: stagSetBackgroundColor + void ParseDefineFont(); //x 10: stagDefineFont + void ParseDefineText(int hasAplha); //x 11: stagDefineText 33: stagDefineText2 + void ParseDoAction(); // 12: stagDoAction + void ParseDefineFontInfo(); //x 13: stagDefineFontInfo + void ParseDefineSound(); // 14: stagDefineSound + void ParseStartSound(); // 15: stagStartSound + void ParseStopSound(); // 16: stagStopSound + void ParseDefineButtonSound(); // 17: stagDefineButtonSound + void ParseSoundStreamHead(); // 18: stagSoundStreamHead + void ParseSoundStreamBlock(); // 19: stagSoundStreamBlock + void ParseDefineBitsLossless(int level); // 20: stagDefineBitsLossless 36: stagDefineBitsLossless2 + void ParseDefineBitsJPEG2(); // 21: stagDefineBitsJPEG2 + void ParseDefineButtonCxform(); // 23: stagDefineButtonCxform + void ParseProtect(); // 24: stagProtect + void ParsePlaceObject2(); // 26: stagPlaceObject2 + void ParseRemoveObject2(); // 28: stagRemoveObject2 + void ParseDefineButton2(); //x 34: stagDefineButton2 + void ParseDefineBitsJPEG3(); // 35: stagDefineBitsJPEG3 + void ParseDefineMouseTarget(); // 38: stagDefineMouseTarget + void ParseDefineSprite(); //x 39: stagDefineSprite + void ParseNameCharacter(); // 40: stagNameCharacter + void ParseFrameLabel(); // 43: stagFrameLabel + void ParseSoundStreamHead2(); // 45: stagSoundStreamHead2 + void ParseDefineMorphShape(); //x 46: stagDefineMorphShape + void ParseDefineFont2(); //x 48: stagDefineFont2 + void ParseUnknown(long,long); + + void ParseTags(int *); + int ParseData(FlashMovie *movie, char * data, long size); + void S_DumpImageGuts(); + +#ifdef DUMP + long save(char *filenam); +#endif +}; + + +#endif /* _SCRIPT_H_ */ diff --git a/core/multimedia/opieplayer/libflash/shape.cc b/core/multimedia/opieplayer/libflash/shape.cc new file mode 100644 index 0000000..0d8df93 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/shape.cc @@ -0,0 +1,1205 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +#define ABS(v) ((v) < 0 ? -(v) : (v)) + +static void prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, FillStyleDef *f, long n); + +static void clearStyles(GraphicDevice *gd, FillStyleDef *f, long n); + +static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape, + ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func); + +// Constructor + +Shape::Shape(long id, int level) : Character(ShapeType, id) +{ + defLevel = level; + + defaultFillStyle.type = f_Solid; + defaultFillStyle.color.red = 0; + defaultFillStyle.color.green = 0; + defaultFillStyle.color.blue = 0; + defaultFillStyle.color.alpha = ALPHA_OPAQUE; + + defaultLineStyle.width = 0; + + // This is to force a first update + lastMat.a = 0; + lastMat.d = 0; + shape_size += sizeof(Shape); + shape_nb ++; + + file_ptr = NULL; + getStyles = 0; + getAlpha = 0; +} + +Shape::~Shape() +{ + if (file_ptr) { + free(file_ptr); + } +} + +void +Shape::setBoundingBox(Rect rect) +{ + boundary = rect; +} + +void +Shape::getBoundingBox(Rect *bb, DisplayListEntry *e) +{ + *bb = boundary; +} + +int +Shape::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform) +{ + //printf("TagId = %d\n", getTagId()); + //if (getTagId() != 220) return 0; + + if (cxform) { + defaultFillStyle.color = cxform->getColor(gd->getForegroundColor()); + } else { + defaultFillStyle.color = gd->getForegroundColor(); + } + defaultFillStyle.color.pixel = gd->allocColor(defaultFillStyle.color); + + drawShape(gd, matrix, cxform, this, ShapeDraw, NULL, 0); + return 0; +} + +void +Shape::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func) +{ + gd->setClipping(0); + drawShape(gd,matrix,0,this,ShapeGetRegion,id,scan_line_func); + gd->setClipping(1); +} + +/************************************************************************/ + +/* create a new path */ + +static void newPath(ShapeParser *shape, + long x, long y) +{ + Path *p; + long x1,y1; + + p=&shape->curPath; + + x1 = shape->matrix->getX(x, y); + y1 = shape->matrix->getY(x, y); + + p->lastX = x1; + p->lastY = y1; + + p->nb_edges = 0; + p->nb_segments = 0; +} + + +static void addSegment1(ShapeParser *shape, + long x, long y, + FillStyleDef *f0, + FillStyleDef *f1, + LineStyleDef *l) +{ + Path *p; + p=&shape->curPath; + + if (l) { + /* a line is defined ... it will be drawn later */ + LineSegment *ls; + + ls = new LineSegment; + if (ls != NULL) { + ls->l = l; + ls->x1 = p->lastX; + ls->y1 = p->lastY; + ls->x2 = x; + ls->y2 = y; + ls->first = (p->nb_segments == 0); + ls->next = NULL; + if (shape->last_line == NULL) { + shape->first_line = ls; + } else { + shape->last_line->next = ls; + } + shape->last_line = ls; + } + } + + /* anti antialiasing not needed if line */ + if (!shape->reverse) { + shape->gd->addSegment(p->lastX,p->lastY,x,y,f0,f1,l ? 0 : 1); + } else { + shape->gd->addSegment(p->lastX,p->lastY,x,y,f1,f0,l ? 0 : 1); + } + + p->lastX = x; + p->lastY = y; + + p->nb_segments++; +} + + +static void addLine(ShapeParser *shape, long x, long y, + FillStyleDef *f0, + FillStyleDef *f1, + LineStyleDef *l) +{ + long x1,y1; + Path *p; + + p=&shape->curPath; + + x1 = shape->matrix->getX(x, y); + y1 = shape->matrix->getY(x, y); + + addSegment1(shape,x1,y1,f0,f1,l); + + p->nb_edges++; +} + + +// This is based on Divide and Conquer algorithm. + +#define BFRAC_BITS 0 +#define BFRAC (1 << BFRAC_BITS) + +static void +bezierBuildPoints (ShapeParser *s, + int subdivisions, + long a1X, long a1Y, + long cX, long cY, + long a2X, long a2Y) +{ + long c1X,c1Y; + long c2X,c2Y; + long X,Y; + long xmin,ymin,xmax,ymax; + + if (subdivisions != 0) { + + /* find the bounding box */ + + if (a1X < cX) { + xmin = a1X; + xmax = cX; + } else { + xmin = cX; + xmax = a1X; + } + if (a2X < xmin) xmin = a2X; + if (a2X > xmax) xmax = a2X; + + if (a1Y < cY) { + ymin = a1Y; + ymax = cY; + } else { + ymin = cY; + ymax = a1Y; + } + if (a2Y < ymin) ymin = a2Y; + if (a2Y > ymax) ymax = a2Y; + + if (((xmax - xmin) + (ymax - ymin)) >= (BFRAC*FRAC*2)) { + // Control point 1 + c1X = (a1X+cX) >> 1; + c1Y = (a1Y+cY) >> 1; + + // Control point 2 + c2X = (a2X+cX) >> 1; + c2Y = (a2Y+cY) >> 1; + + // New point + X = (c1X+c2X) >> 1; + Y = (c1Y+c2Y) >> 1; + + subdivisions--; + + bezierBuildPoints(s, subdivisions, + a1X, a1Y, c1X, c1Y, X, Y); + bezierBuildPoints(s, subdivisions, + X, Y, c2X, c2Y, a2X, a2Y); + + return; + } + } + + addSegment1(s, (a2X+(BFRAC/2)) >> BFRAC_BITS, + (a2Y+(BFRAC/2)) >> BFRAC_BITS, s->f0, s->f1, s->l); +} + +/* this code is broken, but useful to get something */ +static void flushPaths(ShapeParser *s) +{ + LineSegment *ls; + LineStyleDef *l; + long nx,ny,nn,w; + GraphicDevice *gd = s->gd; + + /* draw the filled polygon */ + gd->drawPolygon(); + + /* draw the lines */ + ls = s->first_line; + if (ls != NULL) { + do { + l = ls->l; + +#if 0 + printf("line %d %d %d %d width=%d\n", + ls->x1, ls->y1, ls->x2, ls->y2, l->width); +#endif + + /* XXX: this width is false, but it is difficult (and expensive) + to have the correct one */ + w = ABS((long)(s->matrix->a * l->width)); + + if (w <= ((3*FRAC)/2)) { + w = FRAC; + } +#ifdef THIN_LINES + if (w <= ((3*FRAC)/2)) { + // draw the thin lines only in shapeAction == shapeDraw + if (gd->scan_line_func == NULL) { + gd->setForegroundColor(l->fillstyle.color); + gd->drawLine(ls->x1, ls->y1, ls->x2, ls->y2, w); + } + } else { +#else + { +#endif + /* compute the normal vector */ + + nx = -(ls->y2 - ls->y1); + ny = (ls->x2 - ls->x1); + + /* normalize & width */ + nn = 2 * (long) sqrt(nx * nx + ny * ny); + +#define UL ls->x1 + nx -ny, ls->y1 + ny +nx +#define UR ls->x2 + nx +ny, ls->y2 + ny -nx +#define LL ls->x1 - nx -ny, ls->y1 - ny +nx +#define LR ls->x2 - nx +ny, ls->y2 - ny -nx + + if (nn > 0) { + nx = (nx * w) / nn; + ny = (ny * w) / nn; + + /* top segment */ + gd->addSegment(UL, UR, NULL, &l->fillstyle, 1); + + /* bottom segment */ + gd->addSegment(LL, LR, &l->fillstyle, NULL, 1); + + /* right segment */ + gd->addSegment(UR, LR, &l->fillstyle, NULL, 1); + + /* left segment */ + gd->addSegment(UL, LL, NULL, &l->fillstyle, 1); + + /* draw the line polygon */ + gd->drawPolygon(); + } + } + + ls = ls->next; + } while (ls != NULL); + + /* delete the line structures */ + + ls = s->first_line; + while (ls != NULL) { + LineSegment *ls1; + ls1 = ls->next; + delete ls; + ls = ls1; + } + + /* reset the line pointers */ + s->first_line = NULL; + s->last_line = NULL; + } +} + + +static void addBezier(ShapeParser *shape, + long ctrlX1, long ctrlY1, + long newX1, long newY1, + FillStyleDef *f0, + FillStyleDef *f1, + LineStyleDef *l) +{ + long newX,newY,ctrlX,ctrlY; + Path *p; + + p=&shape->curPath; + + /* note: we do the matrix multiplication before calculating the + bezier points (faster !) */ + + ctrlX = shape->matrix->getX(ctrlX1, ctrlY1); + ctrlY = shape->matrix->getY(ctrlX1, ctrlY1); + newX = shape->matrix->getX(newX1, newY1); + newY = shape->matrix->getY(newX1, newY1); + + shape->f0 = f0; + shape->f1 = f1; + shape->l = l; + + bezierBuildPoints(shape, 3, + p->lastX<lastY<nb_edges++; +} + +/***********************************************************************/ + + +/* bit parser */ + +static void InitBitParser(struct BitParser *b,U8 *buf) +{ + b->ptr = buf; +} + +static void InitBits(struct BitParser *b) +{ + // Reset the bit position and buffer. + b->m_bitPos = 0; + b->m_bitBuf = 0; +} + + + +static inline U8 GetByte(struct BitParser *b) +{ + U8 v; + v = *b->ptr++; + return v; +} + +static inline U16 GetWord(struct BitParser *b) +{ + U8 *s; + U16 v; + s = b->ptr; + v = s[0] | ((U16) s[1] << 8); + b->ptr = s + 2; + return v; +} + +static inline U32 GetDWord(struct BitParser *b) +{ + U32 v; + U8 * s = b->ptr; + v = (U32) s[0] | ((U32) s[1] << 8) | + ((U32) s[2] << 16) | ((U32) s [3] << 24); + b->ptr = s + 4; + return v; +} + +static inline U32 GetBit (struct BitParser *b) +{ + U32 v; + S32 m_bitPos = b->m_bitPos; + U32 m_bitBuf = b->m_bitBuf; + + if (m_bitPos == 0) { + m_bitBuf = (U32)(*b->ptr++) << 24; + m_bitPos = 8; + } + + v = (m_bitBuf >> 31); + + m_bitPos--; + m_bitBuf <<= 1; + + b->m_bitPos = m_bitPos; + b->m_bitBuf = m_bitBuf; + + return v; +} + +static inline U32 GetBits (struct BitParser *b, int n) +{ + U32 v; + S32 m_bitPos = b->m_bitPos; + U32 m_bitBuf = b->m_bitBuf; + + if (n == 0) + return 0; + + while (m_bitPos < n) { + m_bitBuf |= (U32)(*b->ptr++) << (24 - m_bitPos); + m_bitPos += 8; + } + + v = m_bitBuf >> (32 - n); + m_bitBuf <<= n; + m_bitPos -= n; + + b->m_bitPos = m_bitPos; + b->m_bitBuf = m_bitBuf; + return v; +} + +// Get n bits from the string with sign extension. +static inline S32 GetSBits (struct BitParser *b,S32 n) +{ + // Get the number as an unsigned value. + S32 v = (S32) GetBits(b,n); + + // Is the number negative? + if (v & (1L << (n - 1))) + { + // Yes. Extend the sign. + v |= -1L << n; + } + + return v; +} + + + +/************************************************************************/ + +static void GetMatrix(BitParser *b, Matrix* mat) +{ + InitBits(b); + + // Scale terms + if (GetBit(b)) + { + int nBits = (int) GetBits(b,5); + mat->a = (float)(GetSBits(b,nBits))/(float)0x10000; + mat->d = (float)(GetSBits(b,nBits))/(float)0x10000; + } + else + { + mat->a = mat->d = 1.0; + } + + // Rotate/skew terms + if (GetBit(b)) + { + int nBits = (int)GetBits(b,5); + mat->c = (float)(GetSBits(b,nBits))/(float)0x10000; + mat->b = (float)(GetSBits(b,nBits))/(float)0x10000; + } + else + { + mat->b = mat->c = 0.0; + } + + // Translate terms + int nBits = (int) GetBits(b,5); + mat->tx = GetSBits(b,nBits); + mat->ty = GetSBits(b,nBits); +} + +static FillStyleDef * ParseFillStyle(ShapeParser *shape, long *n, long getAlpha) +{ + BitParser *b = &shape->bit_parser; + FillStyleDef *defs; + U16 i = 0; + + // Get the number of fills. + U16 nFills = GetByte(b); + + // Do we have a larger number? + if (nFills == 255) + { + // Get the larger number. + nFills = GetWord(b); + } + + *n = nFills; + defs = new FillStyleDef[ nFills ]; + if (defs == NULL) return NULL; + + // Get each of the fill style. + for (i = 0; i < nFills; i++) + { + U16 fillStyle = GetByte(b); + + defs[i].type = (FillType) fillStyle; + + if (fillStyle & 0x10) + { + defs[i].type = (FillType) (fillStyle & 0x12); + + // Get the gradient matrix. + GetMatrix(b,&(defs[i].matrix)); + + // Get the number of colors. + defs[i].gradient.nbGradients = GetByte(b); + + // Get each of the colors. + for (U16 j = 0; j < defs[i].gradient.nbGradients; j++) + { + defs[i].gradient.ratio[j] = GetByte(b); + defs[i].gradient.color[j].red = GetByte(b); + defs[i].gradient.color[j].green = GetByte(b); + defs[i].gradient.color[j].blue = GetByte(b); + if (getAlpha) { + defs[i].gradient.color[j].alpha = GetByte(b); + } else { + defs[i].gradient.color[j].alpha = ALPHA_OPAQUE; + } + } + } + else if (fillStyle & 0x40) + { + defs[i].type = (FillType) (fillStyle & 0x41); + + // Get the bitmapId + defs[i].bitmap = (Bitmap *)shape->dict->getCharacter(GetWord(b)); + // Get the bitmap matrix. + GetMatrix(b,&(defs[i].matrix)); + } + else + { + defs[i].type = (FillType) 0; + + // A solid color + defs[i].color.red = GetByte(b); + defs[i].color.green = GetByte(b); + defs[i].color.blue = GetByte(b); + if (getAlpha) { + defs[i].color.alpha = GetByte(b); + } else { + defs[i].color.alpha = ALPHA_OPAQUE; + } + } + } + + return defs; +} + +static LineStyleDef * ParseLineStyle(ShapeParser *shape, long *n, long getAlpha) +{ + BitParser *b = &shape->bit_parser; + LineStyleDef *defs,*def; + FillStyleDef *f; + long i; + + // Get the number of lines. + U16 nLines = GetByte(b); + + // Do we have a larger number? + if (nLines == 255) + { + // Get the larger number. + nLines = GetWord(b); + } + + *n = nLines; + defs = new LineStyleDef[ nLines ]; + if (defs == NULL) return NULL; + + // Get each of the line styles. + for (i = 0; i < nLines; i++) + { + def=&defs[i]; + def->width = GetWord(b); + def->color.red = GetByte(b); + def->color.green = GetByte(b); + def->color.blue = GetByte(b); + if (getAlpha) { + def->color.alpha = GetByte(b); + } else { + def->color.alpha = ALPHA_OPAQUE; + } + + f=&def->fillstyle; + f->type = f_Solid; + f->color = def->color; + if (shape->cxform) { + f->color = shape->cxform->getColor(f->color); + } + f->color.pixel = shape->gd->allocColor(f->color); + } + + return defs; +} + +/* 0 = end of shape */ +static int ParseShapeRecord(ShapeParser *shape, ShapeRecord *sr, long getAlpha) +{ + BitParser *b = &shape->bit_parser; + + // Determine if this is an edge. + BOOL isEdge = (BOOL) GetBit(b); + + if (!isEdge) + { + // Handle a state change + U16 flags = (U16) GetBits(b,5); + + // Are we at the end? + if (flags == 0) + { + // End of shape + return 0; + } + + sr->type = shapeNonEdge; + sr->flags = (ShapeFlags)flags; + + // Process a move to. + if (flags & flagsMoveTo) + { + U16 nBits = (U16) GetBits(b,5); + sr->x = GetSBits(b,nBits); + sr->y = GetSBits(b,nBits); + } + + // Get new fill info. + if (flags & flagsFill0) + { + sr->fillStyle0 = GetBits(b,shape->m_nFillBits); + } + if (flags & flagsFill1) + { + sr->fillStyle1 = GetBits(b,shape->m_nFillBits); + } + + // Get new line info + if (flags & flagsLine) + { + sr->lineStyle = GetBits(b,shape->m_nLineBits); + } + + // Check to get a new set of styles for a new shape layer. + if (flags & flagsNewStyles) + { + FillStyleDef *fillDefs; + LineStyleDef *lineDefs; + long n; + + // Parse the style. + fillDefs = ParseFillStyle(shape, &n, getAlpha); + if (fillDefs == NULL) return 0; + + sr->newFillStyles = fillDefs; + sr->nbNewFillStyles = n; + + lineDefs = ParseLineStyle(shape, &n, getAlpha); + if (lineDefs == NULL) return 0; + + sr->newLineStyles = lineDefs; + sr->nbNewLineStyles = n; + + InitBits(b); // Bug ! + + // Reset. + shape->m_nFillBits = (U16) GetBits(b,4); + shape->m_nLineBits = (U16) GetBits(b,4); + } + + //if (flags & flagsEndShape) + //printf("\tEnd of shape.\n\n"); + + return flags & flagsEndShape ? 0 : 1; + } + else + { + if (GetBit(b)) + { + sr->type = shapeLine; + + // Handle a line + U16 nBits = (U16) GetBits(b,4) + 2; // nBits is biased by 2 + + // Save the deltas + if (GetBit(b)) + { + // Handle a general line. + sr->dX = GetSBits(b,nBits); + sr->dY = GetSBits(b,nBits); + } + else + { + // Handle a vert or horiz line. + if (GetBit(b)) + { + // Vertical line + sr->dY = GetSBits(b,nBits); + sr->dX = 0; + } + else + { + // Horizontal line + sr->dX = GetSBits(b,nBits); + sr->dY = 0; + } + } + } + else + { + sr->type = shapeCurve; + + // Handle a curve + U16 nBits = (U16) GetBits(b,4) + 2; // nBits is biased by 2 + + // Get the control + sr->ctrlX = GetSBits(b,nBits); + sr->ctrlY = GetSBits(b,nBits); + + // Get the anchor + sr->anchorX = GetSBits(b,nBits); + sr->anchorY = GetSBits(b,nBits); + } + + return 1; + } +} + +static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape, + ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func) +{ + LineStyleDef *l; + FillStyleDef *f0; + FillStyleDef *f1; + ShapeRecord sr1,*sr = &sr1; + int firstPoint; + long lastX,lastY; + LineStyleDef *curLineStyle; + long curNbLineStyles; + FillStyleDef *curFillStyle; + long curNbFillStyles; + StyleList *sl; + ShapeParser sp1,*sp=&sp1; + BitParser *b; + Matrix mat,*matrix; + + mat = (*gd->adjust) * (*matrix1); + matrix = &mat; + + sp->reverse = (mat.a * mat.d) < 0; + + curLineStyle = NULL; + curNbLineStyles = 0; + curFillStyle = NULL; + curNbFillStyles = 0; + sp->style_list = NULL; + + sp->shape = shape; + sp->gd = gd; + sp->matrix = matrix; + sp->cxform = cxform; + sp->dict = shape->dict; + + if (shapeAction == ShapeGetRegion) { + gd->scan_line_func = scan_line_func; + gd->scan_line_func_id = id; + } else { + gd->scan_line_func = NULL; + } + + b = &sp->bit_parser; + InitBitParser(b,shape->file_ptr); + + if (shape->getStyles) { + // ShapeWithStyle + curFillStyle = ParseFillStyle(sp, &curNbFillStyles, shape->getAlpha); + if (curFillStyle == NULL) return; + + curLineStyle = ParseLineStyle(sp, &curNbLineStyles, shape->getAlpha); + if (curLineStyle == NULL) return; + + sl = new StyleList; + if (sl == NULL) return; + + sl->next = NULL; + sl->newFillStyles = curFillStyle; + sl->nbNewFillStyles = curNbFillStyles; + sl->newLineStyles = curLineStyle; + sl->nbNewLineStyles = curNbLineStyles; + + sp->style_list = sl; + + if (shapeAction == ShapeDraw) { + prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles); + } + } + + InitBits(b); + sp->m_nFillBits = (U16) GetBits(b,4); + sp->m_nLineBits = (U16) GetBits(b,4); + + l = 0; + f0 = 0; + f1 = 0; + firstPoint = 1; + lastX = 0; + lastY = 0; + sp->curPath.nb_edges = 0; + sp->first_line = NULL; + sp->last_line = NULL; + + for(;;) { + if (ParseShapeRecord(sp, sr, shape->getAlpha) == 0) break; + + switch (sr->type) + { + case shapeNonEdge: + if (sr->flags & flagsNewStyles) { + + curFillStyle = sr->newFillStyles; + curNbFillStyles = sr->nbNewFillStyles; + curLineStyle = sr->newLineStyles; + curNbLineStyles = sr->nbNewLineStyles; + + sl = new StyleList; + sl->next = sp->style_list; + sl->newFillStyles = sr->newFillStyles; + sl->nbNewFillStyles = sr->nbNewFillStyles; + sl->newLineStyles = sr->newLineStyles; + sl->nbNewLineStyles = sr->nbNewLineStyles; + + sp->style_list = sl; + + if (shapeAction == ShapeDraw) { + prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles); + } + } + if (sr->flags & flagsFill0) { + if (sr->fillStyle0) { + if (curFillStyle) { + f0 = &curFillStyle[sr->fillStyle0-1]; + } else { + f0 = &shape->defaultFillStyle; + } + } else { + f0 = 0; + } + } + if (sr->flags & flagsFill1) { + if (sr->fillStyle1) { + if (curFillStyle) { + f1 = &curFillStyle[sr->fillStyle1-1]; + } else { + f1 = &shape->defaultFillStyle; + } + } else { + f1 = 0; + } + } + if (sr->flags & flagsLine) { + if (sr->lineStyle) { + l = &curLineStyle[sr->lineStyle-1]; + } else { + l = 0; + } + } + if (sr->flags & flagsMoveTo) { + if (sp->curPath.nb_edges == 0) { + /* if no edges, draw the polygon, then the lines */ + flushPaths(sp); + } + + newPath(sp, sr->x, sr->y); + firstPoint = 0; + + lastX = sr->x; + lastY = sr->y; + +#if PRINT + printf("---------\nX,Y = %4d,%4d\n", sr->x/20, sr->y/20); +#endif + } + break; + case shapeCurve: + // Handle Bezier Curves !!! + if (firstPoint) { + newPath(sp, 0, 0); + firstPoint = 0; + } + { + long newX,newY,ctrlX,ctrlY; + + ctrlX = lastX+sr->ctrlX; + ctrlY = lastY+sr->ctrlY; + newX = ctrlX+sr->anchorX; + newY = ctrlY+sr->anchorY; + +#if 1 + addBezier(sp, ctrlX, ctrlY, newX, newY, f0 , f1, l); +#else + addLine(sp, newX, newY, f0, f1, l); +#endif + + lastX = newX; + lastY = newY; + } + break; + case shapeLine: + if (firstPoint) { + newPath(sp, 0, 0); + firstPoint = 0; + } + + lastX += sr->dX; + lastY += sr->dY; + + addLine(sp, lastX, lastY, f0, f1, l); +#if PRINT + printf(" X, Y = %4d,%4d\n", lastX/20, lastY/20); +#endif + break; + } + } + + /* XXX: should test if there is something to draw */ + flushPaths(sp); + + /* free the styles */ + while (sp->style_list) { + StyleList *sl; + + sl=sp->style_list; + sp->style_list = sl->next; + + if (shapeAction == ShapeDraw) { + clearStyles(gd, sl->newFillStyles, sl->nbNewFillStyles); + } + + delete[] sl->newFillStyles; + delete[] sl->newLineStyles; + + delete sl; + } +} + +static void +prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, + FillStyleDef *ftab, long n) +{ + long fs; + FillStyleDef *f; + + for(fs = 0; fs < n; fs++) + { + f = ftab + fs; + switch (f->type) + { + case f_None: + break; + case f_Solid: + if (cxform) { + f->color = cxform->getColor(f->color); + } + f->color.pixel = gd->allocColor(f->color); + break; + case f_LinearGradient: + case f_RadialGradient: + { + Matrix mat; + int n,r,l; + long red, green, blue, alpha; + long dRed, dGreen, dBlue, dAlpha; + long min,max; + Matrix *m; + + mat = *(matrix) * f->matrix; + // Compute inverted matrix + f->gradient.imat = mat.invert(); + + /* renormalize the matrix */ + m=&f->gradient.imat; + if (f->type == f_LinearGradient) { + m->a = m->a * FRAC * (1/128.0) * 65536.0; + m->b = m->b * FRAC * (1/128.0) * 65536.0; + m->tx = (long) ((m->tx + 16384) * (1/128.0) * 65536.0); + } else { + m->a = m->a * FRAC * (1/64.0) * 65536.0; + m->b = m->b * FRAC * (1/64.0) * 65536.0; + m->c = m->c * FRAC * (1/64.0) * 65536.0; + m->d = m->d * FRAC * (1/64.0) * 65536.0; + m->tx = (long) (m->tx * (1/64.0) * 65536.0); + m->ty = (long) (m->ty * (1/64.0) * 65536.0); + } + + // Reset translation in inverted matrix + f->gradient.has_alpha = 0; + + // Build a 256 color ramp + f->gradient.ramp = new Color[256]; + if (f->gradient.ramp == NULL) { + // Invalidate fill style + f->type = f_None; + continue; + } + + // Store min and max + min = f->gradient.ratio[0]; + max = f->gradient.ratio[f->gradient.nbGradients-1]; + for(r=0; r < f->gradient.nbGradients-1; r++) + { + Color start,end; + + l = f->gradient.ratio[r+1]-f->gradient.ratio[r]; + if (l == 0) continue; + + if (cxform) { + start = cxform->getColor(f->gradient.color[r]); + end = cxform->getColor(f->gradient.color[r+1]); + } else { + start = f->gradient.color[r]; + end = f->gradient.color[r+1]; + } + + if (start.alpha != ALPHA_OPAQUE || + end.alpha != ALPHA_OPAQUE) { + f->gradient.has_alpha = 1; + } + + dRed = end.red - start.red; + dGreen = end.green - start.green; + dBlue = end.blue - start.blue; + dAlpha = end.alpha - start.alpha; + + dRed = (dRed<<16)/l; + dGreen = (dGreen<<16)/l; + dBlue = (dBlue<<16)/l; + dAlpha = (dAlpha<<16)/l; + + red = start.red <<16; + green = start.green <<16; + blue = start.blue <<16; + alpha = start.alpha <<16; + + for (n=f->gradient.ratio[r]; n<=f->gradient.ratio[r+1]; n++) { + f->gradient.ramp[n].red = red>>16; + f->gradient.ramp[n].green = green>>16; + f->gradient.ramp[n].blue = blue>>16; + f->gradient.ramp[n].alpha = alpha>>16; + + f->gradient.ramp[n].pixel = gd->allocColor(f->gradient.ramp[n]); + red += dRed; + green += dGreen; + blue += dBlue; + alpha += dAlpha; + } + } + for(n=0; ngradient.ramp[n] = f->gradient.ramp[min]; + } + for(n=max; n<256; n++) { + f->gradient.ramp[n] = f->gradient.ramp[max]; + } + } + break; + case f_TiledBitmap: + case f_clippedBitmap: + if (f->bitmap) { + Matrix *m; + + f->cmap = gd->getColormap(f->bitmap->colormap, + f->bitmap->nbColors, cxform); + if (f->cmap == NULL) { + /* Get the normal cmap anyway */ + f->cmap = f->bitmap->colormap; + } + + f->bitmap_matrix = *(matrix) * f->matrix; + + f->bitmap_matrix = f->bitmap_matrix.invert(); + + m=&f->bitmap_matrix; + m->a = m->a * FRAC * 65536.0; + m->b = m->b * FRAC * 65536.0; + m->c = m->c * FRAC * 65536.0; + m->d = m->d * FRAC * 65536.0; + m->tx = (long) (m->tx * 65536.0); + m->ty = (long) (m->ty * 65536.0); + + f->alpha_table = NULL; + + if (f->bitmap->alpha_buf && cxform) { + unsigned char *alpha_table; + int i; + + alpha_table = (unsigned char *)malloc (256); + if (alpha_table != NULL) { + for(i=0;i<256;i++) { + alpha_table[i] = cxform->getAlpha(i); + } + } + f->alpha_table = alpha_table; + } + } + break; + } + } +} + +static void +clearStyles(GraphicDevice *gd, FillStyleDef *ftab, long n) +{ + long fs; + FillStyleDef *f; + + for(fs = 0; fs < n; fs++) + { + f = ftab + fs; + switch (f->type) + { + case f_Solid: + break; + case f_LinearGradient: + case f_RadialGradient: + if (f->gradient.ramp) { + delete f->gradient.ramp; + } + break; + case f_TiledBitmap: + case f_clippedBitmap: + if (f->bitmap) { + if (f->cmap && f->cmap != f->bitmap->colormap) delete f->cmap; + if (f->alpha_table) free(f->alpha_table); + } + break; + case f_None: + break; + } + } +} + diff --git a/core/multimedia/opieplayer/libflash/shape.h b/core/multimedia/opieplayer/libflash/shape.h new file mode 100644 index 0000000..120ec94 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/shape.h @@ -0,0 +1,181 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _SHAPE_H_ +#define _SHAPE_H_ + +struct LineStyleDef { + long width; + Color color; + FillStyleDef fillstyle; +}; + +enum ShapeRecordType { + shapeNonEdge, + shapeCurve, + shapeLine +}; + +enum ShapeFlags { + flagsMoveTo = 0x01, + flagsFill0 = 0x02, + flagsFill1 = 0x04, + flagsLine = 0x08, + flagsNewStyles = 0x10, + flagsEndShape = 0x80 +}; + +struct ShapeRecord { + ShapeRecordType type; + + // Non Edge + ShapeFlags flags; + long x,y; // Moveto + long fillStyle0; + long fillStyle1; + long lineStyle; + FillStyleDef *newFillStyles; // Array + long nbNewFillStyles; + LineStyleDef *newLineStyles; // Array + long nbNewLineStyles; + + // Curve Edge + long ctrlX, ctrlY; + long anchorX, anchorY; + + // Straight Line + long dX,dY; + + struct ShapeRecord *next; + + ShapeRecord() { + shaperecord_size += sizeof(ShapeRecord); + shaperecord_nb++; + } + +}; + +enum ShapeAction { + ShapeDraw, + ShapeGetRegion +}; + +struct LineSegment { + long x1,y1,x2,y2; + char first; + LineStyleDef *l; + struct LineSegment *next; +}; + +struct Path { + long lastX,lastY; + int nb_edges; + int nb_segments; +}; + +struct StyleList { + FillStyleDef *newFillStyles; // Array + long nbNewFillStyles; + LineStyleDef *newLineStyles; // Array + long nbNewLineStyles; + + StyleList *next; +}; + + +/* fast bit parser */ +struct BitParser { + // Bit Handling + S32 m_bitPos; + U32 m_bitBuf; + + U8 *ptr; +}; + +class Shape; + +/* state of the shape parser */ +struct ShapeParser { + Dict *dict; /* XXX: should be put elsewhere */ + + BitParser bit_parser; + S32 m_nFillBits; + S32 m_nLineBits; + + StyleList *style_list; + Matrix *matrix; + Path curPath; + int reverse; + + /* line rasteriser */ + LineSegment *first_line,*last_line; + GraphicDevice *gd; + Cxform *cxform; + Shape *shape; + + FillStyleDef *f0; + FillStyleDef *f1; + LineStyleDef *l; +}; + +class Shape : public Character { + public: + int defLevel; // 1,2 or 3 + + + Rect boundary; + FillStyleDef defaultFillStyle; + LineStyleDef defaultLineStyle; + + Matrix lastMat; + /* parsing for the rendering stage (saves a lot of memory & + may not reduce significantly the size). These variables + should be in another structure (no state need to be + maintained between two renderings) */ + int getAlpha, getStyles; + unsigned char *file_ptr; + Dict *dict; /* XXX: should be put elsewhere */ + +protected: + void drawLines(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, long, long); + void buildSegmentList(Segment **segs, int height, long &n, Matrix *matrix, int update, int reverse); + Segment *progressSegments(Segment *, long); + Segment *newSegments(Segment *, Segment *); + +public: + Shape(long id = 0 , int level = 1); + ~Shape(); + + void setBoundingBox(Rect rect); + int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform); + void getRegion(GraphicDevice *gd, Matrix *matrix, + void *id, ScanLineFunc scan_line_func); + + void getBoundingBox(Rect *bb, DisplayListEntry *); + +#ifdef DUMP + void dump(BitStream *bs); + void dumpShapeRecords(BitStream *bs, int alpha); + void dumpFillStyles(BitStream *bs, FillStyleDef *defs, long n, int alpha); + void dumpLineStyles(BitStream *bs, LineStyleDef *defs, long n, int alpha); + void checkBitmaps(BitStream *bs); +#endif +}; + +#endif /* _SHAPE_H_ */ diff --git a/core/multimedia/opieplayer/libflash/sound.cc b/core/multimedia/opieplayer/libflash/sound.cc new file mode 100644 index 0000000..e93f9b5 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/sound.cc @@ -0,0 +1,439 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#include +#include +#include +#ifndef NOSOUND +#include +#endif + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +#define PRINT 0 + +//////////// SOUND + +Sound::Sound(long id) : Character(SoundType, id) +{ + samples = 0; + stereo = 0; + soundRate = 0; + sampleSize = 1; +} + +Sound::~Sound() +{ + if (samples) { + delete samples; + } +} + +void +Sound::setSoundFlags(long f) { + switch (GET_SOUND_RATE_CODE(f)) { + case 0: + soundRate = 5500; + break; + case 1: + soundRate = 11000; + break; + case 2: + soundRate = 22000; + break; + case 3: + soundRate = 44000; + break; + } + if (f & soundIs16bit) { + sampleSize = 2; + } + if (f & soundIsStereo) { + stereo = 1; + } + +#if PRINT + printf("-----\nFlags = %2x\n", f); + printf("Rate = %d kHz ", soundRate); + printf("SampleSize = %d byte(s) ", sampleSize); + if (f & soundIsStereo) { + printf("Stereo "); + } else { + printf("Mono "); + } + if (f & soundIsADPCMCompressed) { + printf("ADPCM\n"); + } else { + printf("Raw\n"); + } +#endif +} + +char * +Sound::setNbSamples(long n) { + long size; + + nbSamples = n; + + size = nbSamples * (stereo ? 2 : 1) * sampleSize; + + samples = new char[ size ]; + + memset((char *)samples,0, size); + + return samples; +} + +long +Sound::getRate() { + return soundRate; +} + +long +Sound::getChannel() { + return stereo ? 2 : 1; +} + +long +Sound::getNbSamples() { + return nbSamples; +} + +long +Sound::getSampleSize() { + return sampleSize; +} + +char * +Sound::getSamples() { + return samples; +} + +//////////// SOUND MIXER + +long SoundMixer::dsp = -1; // Init of descriptor +long SoundMixer::blockSize = 0; // Driver sound buffer size +long SoundMixer::nbInst = 0; // Nb SoundMixer instances +long SoundMixer::sampleSize = 0; +long SoundMixer::stereo = 0; +long SoundMixer::soundRate = 0; +char *SoundMixer::buffer = 0; + +SoundMixer::SoundMixer(char *device) +{ +#ifndef NOSOUND + int status; + long fmt; + + list = 0; // No sound to play + + if (nbInst++) { + // Device is already open + return; + } + + dsp = open(device,O_WRONLY); + if (dsp < 0) { + perror("open dsp"); + return; + } + + // Reset device + status = ioctl(dsp, SNDCTL_DSP_RESET); + if (status < 0) perror("ioctl SNDCTL_DSP_RESET"); + + // Set sample size + fmt = AFMT_S16_LE; + sampleSize = 2; + status = ioctl(dsp, SNDCTL_DSP_SETFMT, &fmt); + if (status < 0) perror("ioctl SNDCTL_DSP_SETFMT"); + + if (status) { + fmt = AFMT_U8; + sampleSize = 1; + status = ioctl(dsp, SNDCTL_DSP_SETFMT, &fmt); + if (status < 0) perror("ioctl SNDCTL_DSP_SETFMT"); + } + + // Set stereo channel + stereo = 1; + status = ioctl(dsp, SNDCTL_DSP_STEREO, &stereo); + + if (status) { + stereo = 0; + } + + // Set sound rate in Hertz + soundRate = 11000; + status = ioctl(dsp, SNDCTL_DSP_SPEED, &soundRate); + if (status < 0) perror("ioctl SNDCTL_DSP_SPEED"); + + // Get device buffer size + status = ioctl(dsp, SNDCTL_DSP_GETBLKSIZE, &blockSize); + if (status < 0) perror("ioctl SNDCTL_DSP_GETBLKSIZE"); + if (blockSize < 1024) { + blockSize = 32768; + } + blockSize *= 2; + + buffer = (char *)malloc(blockSize); + if (buffer == 0) { + close(dsp); + dsp = -1; + } + +#if PRINT + int caps; + + ioctl(dsp,SNDCTL_DSP_GETCAPS, &caps); + printf("Audio capabilities = %x\n", caps); + printf("Sound Rate = %d\n", soundRate); + printf("Stereo = %d\n", stereo); + printf("Sample Size = %d\n", sampleSize); + printf("Buffer Size = %d\n", blockSize); +#endif /* PRINT */ + +#endif /* NOSOUND */ +} + +SoundMixer::~SoundMixer() +{ + if (--nbInst == 0) { + if (dsp > 0) { + close(dsp); + free(buffer); + } + } +} + +void +SoundMixer::stopSounds() +{ +#ifndef NOSOUND + SoundList *sl,*del; + + for(sl = list; sl; ) { + del = sl; + sl = sl->next; + delete del; + } + list = 0; +#endif +} + +void +SoundMixer::startSound(Sound *sound) +{ +#ifndef NOSOUND + SoundList *sl; + + if (sound) { + // Add sound in list + sl = new SoundList; + sl->rate = sound->getRate(); + sl->stereo = (sound->getChannel() == 2); + sl->sampleSize = sound->getSampleSize(); + sl->current = sound->getSamples(); + sl->remaining = sound->getSampleSize()*sound->getNbSamples()*sound->getChannel(); + sl->next = list; + list = sl; + } +#endif +} + +long +SoundMixer::playSounds() +{ +#ifndef NOSOUND + audio_buf_info bufInfo; + long nbBytes, n; + SoundList *sl,*prev; + int status; + + // Init failed + if (dsp < 0) return 0; + + // No sound to play + if (list == 0) return 0; + + // Get free DMA buffer space + status = ioctl(dsp, SNDCTL_DSP_GETOSPACE, &bufInfo); + + // Free space is not large enough to output data without blocking + // But there are still sounds to play. We must wait. + if (bufInfo.bytes < blockSize) return 1; + + nbBytes = 0; + + // Fill buffer with silence. + memset((void*)buffer, 0, blockSize); + + prev = 0; + sl = list; + while(sl) { + + // Ask sound to fill the buffer + // according to device capabilities + n = fillSoundBuffer(sl, buffer, blockSize); + + // Remember the largest written size + if (n > nbBytes) { + nbBytes = n; + } + + // No more samples for this sound + if (sl->remaining == 0) { + // Remove sound from list + if (prev) { + prev->next = sl->next; + delete sl; + sl = prev->next; + } else { + list = sl->next; + delete sl; + sl = list; + } + } else { + sl = sl->next; + } + } + + if (nbBytes) { + // At last ! Play It ! + write(dsp,buffer,nbBytes); + status = ioctl(dsp, SNDCTL_DSP_POST); + } + + return nbBytes; +#else + return 0; +#endif +} + +long +SoundMixer::fillSoundBuffer(SoundList *sl, char *buff, long buffSize) +{ + long sampleLeft, sampleRight; + long skipOut, skipOutInit; + long skipIn, skipInInit; + long freqRatio; + long totalOut = 0; + + sampleLeft = sampleRight = 0; + skipOutInit = skipInInit = 0; + + freqRatio = sl->rate / soundRate; + if (freqRatio) { + skipOutInit = freqRatio - 1; + skipInInit = 0; + } + + freqRatio = soundRate / sl->rate; + if (freqRatio) { + skipInInit = freqRatio - 1; + skipOutInit = 0; + } + + skipOut = skipOutInit; + skipIn = skipInInit; + while (buffSize && sl->remaining) { + if (skipIn-- == 0) { + // Get sampleLeft + if (sl->sampleSize == 2) { + sampleLeft = (long)(*(short *)(sl->current)); + if (sampleSize == 1) { + sampleLeft = (sampleLeft >> 8) &0xff; + } + } else { + sampleLeft = (long)*(sl->current); + if (sampleSize == 2) { + sampleLeft <<= 8; + } + } + sl->current += sl->sampleSize; + sl->remaining -= sl->sampleSize; + + if (sl->stereo) { + // Get sampleRight + if (sl->sampleSize == 2) { + sampleRight = (long)(*(short *)(sl->current)); + if (sampleSize == 1) { + sampleRight = (sampleRight >> 8) &0xff; + } + } else { + sampleRight = (long)*(sl->current); + if (sampleSize == 2) { + sampleRight <<= 8; + } + } + sl->current += sl->sampleSize; + sl->remaining -= sl->sampleSize; + + } else { + sampleRight = sampleLeft; + } + + skipIn = skipInInit; + } + + if (skipOut-- == 0) { + // Output + if (stereo) { + if (sampleSize == 2) { + *((short *)buff) += sampleLeft/2; + buffSize -= sampleSize; + buff += sampleSize; + *((short *)buff) += sampleRight/2; + buffSize -= sampleSize; + buff += sampleSize; + } else { + *((char *)buff) += sampleLeft/2; + buffSize -= sampleSize; + buff += sampleSize; + *((char *)buff) += sampleRight/2; + buffSize -= sampleSize; + buff += sampleSize; + } + totalOut += 2*sampleSize; + } else { + if (sampleSize == 2) { + *((short *)buff) += (sampleLeft+sampleRight)>>2; + buffSize -= sampleSize; + buff += sampleSize; + } else { + *((char *)buff) += (sampleLeft+sampleRight)>>2; + buffSize -= sampleSize; + buff += sampleSize; + } + totalOut += sampleSize; + } + + skipOut = skipOutInit; + } + } + + return totalOut; +} diff --git a/core/multimedia/opieplayer/libflash/sound.h b/core/multimedia/opieplayer/libflash/sound.h new file mode 100644 index 0000000..c53773d --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/sound.h @@ -0,0 +1,83 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _SOUND_H_ +#define _SOUND_H_ + +#define GET_SOUND_RATE_CODE(f) (((f)&0x0c)>>2) + +class Sound : public Character { + long soundRate; // In hz + long stereo; // True if stereo sound + long sampleSize; // 1 or 2 bytes + + char *samples; // Array of samples + long nbSamples; + +public: + Sound(long id); + ~Sound(); + void setSoundFlags(long f); + char *setNbSamples(long n); + + long getRate(); + long getChannel(); + long getNbSamples(); + long getSampleSize(); + char *getSamples(); +}; + +struct SoundList { + long rate; + long stereo; + long sampleSize; + long nbSamples; + long remaining; + char *current; + + SoundList *next; +}; + +class SoundMixer { + + SoundList *list; + +// Class variables +static long dsp; // Descriptor for /dev/dsp +static char * buffer; // DMA buffer +static long blockSize; +static long nbInst; // Number of instances + + // Sound Device Capabilities +static long soundRate; // In hz +static long stereo; // True if stereo sound +static long sampleSize; // 1 or 2 bytes + +public: + SoundMixer(char*); + ~SoundMixer(); + + void startSound(Sound *sound); // Register a sound to be played + void stopSounds(); // Stop every current sounds in the instance + + long playSounds(); // Actually play sounds of all instances + long fillSoundBuffer(SoundList *, char *buffer, long bufferSize); // Fill sound buffer +}; + +#endif /* _SOUND_H_ */ diff --git a/core/multimedia/opieplayer/libflash/sprite.cc b/core/multimedia/opieplayer/libflash/sprite.cc new file mode 100644 index 0000000..de53095 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/sprite.cc @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +Sprite::Sprite(FlashMovie *movie, long id, long frameCount) : Character(SpriteType, id) +{ + program = new Program(movie, frameCount); + if (program == NULL) return; + if (program->totalFrames == 0) { + delete program; + program = NULL; + return; + } + program->dl->isSprite = 1; +} + +Sprite::~Sprite() +{ + delete program; +} + +void +Sprite::reset() +{ + program->rewindMovie(); +} + +int +Sprite::isSprite(void) +{ + return 1; +} + +Program * +Sprite::getProgram() +{ + return program; +} + +int +Sprite::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform) +{ + return program->dl->render(gd,matrix,cxform); +} + +ActionRecord * +Sprite::eventHandler(GraphicDevice *gd, FlashEvent *event) +{ +#if 0 + DisplayList *dl; + ActionRecord *actions; + + dl = program->getDisplayList(); + actions = dl->processEvent(gd, event); + if (actions) { + program->doAction(actions,0); + } + return actions; +#endif + return NULL; +} + +void +Sprite::getBoundingBox(Rect *bb, DisplayListEntry *e) +{ + program->dl->getBoundary(bb); +} diff --git a/core/multimedia/opieplayer/libflash/sprite.h b/core/multimedia/opieplayer/libflash/sprite.h new file mode 100644 index 0000000..2ea64bc --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/sprite.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _SPRITE_H_ +#define _SPRITE_H_ + +class Sprite : public Character { +public: + Program *program; + + Sprite(FlashMovie *movie, long id, long frameCount); + ~Sprite(); + Program *getProgram(); + int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform); + int hasEventHandler(); + void reset(); + ActionRecord *eventHandler(GraphicDevice *, FlashEvent *); + int isSprite(void); + void getBoundingBox(Rect *bb, DisplayListEntry *de); +}; + +#endif /* _SPRITE_H_ */ diff --git a/core/multimedia/opieplayer/libflash/sqrt.cc b/core/multimedia/opieplayer/libflash/sqrt.cc new file mode 100644 index 0000000..0d8295e --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/sqrt.cc @@ -0,0 +1,4099 @@ +unsigned char SQRT[] = { + +0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3, +4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5, +5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6, +6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, +9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10, +10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11, +11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, +12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, +12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13, +13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, +13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14, +14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, +14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, +16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, +16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, +17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, +17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18, +18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, +20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, +20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, +20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21, +21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, +21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21, +21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22, +22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, +22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, +22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, +23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, +23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, +24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, +24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, +24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, +24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, +25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, +25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, +25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26, +26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, +26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, +26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27, +27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27, +27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27, +27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27, +28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, +28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, +28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, +28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29, +29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, +29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, +29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29, +29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31, +31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31, +31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31, +31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33, +33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33, +33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33, +33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33, +33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34, +34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34, +34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34, +34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34, +34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35, +36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, +36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, +36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, +36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36, +36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37, +37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, +37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, +37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, +37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37, +37,37,37,37,38,38,38,38,38,38,38,38,38,38,38,38, +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, +38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, +38,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, +40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, +40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, +40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, +40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40, +40,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, +41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, +41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, +41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, +41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, +41,41,41,41,42,42,42,42,42,42,42,42,42,42,42,42, +42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, +42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, +42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, +42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42, +42,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43, +43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, +43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, +43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, +43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, +43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43, +44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, +44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, +44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, +44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, +44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44, +44,44,44,44,44,44,44,44,44,45,45,45,45,45,45,45, +45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, +45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, +45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, +45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, +45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45, +45,45,45,45,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46, +46,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48, +48,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49, +49,49,49,49,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50, +50,50,50,50,50,50,50,50,50,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52, +52,52,52,52,52,52,52,52,52,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53, +53,53,53,53,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54, +54,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56, +56,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57, +57,57,57,57,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58, +58,58,58,58,58,58,58,58,58,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, +60,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61, +61,61,61,61,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62, +62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64, +64,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65, +65,65,65,65,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66, +66,66,66,66,66,66,66,66,66,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69, +69,69,69,69,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70, +70,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72, +72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73, +73,73,73,73,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74, +74,74,74,74,74,74,74,74,74,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76, +76,76,76,76,76,76,76,76,76,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, +77,77,77,77,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78, +78,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80, +80,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81, +81,81,81,81,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82, +82,82,82,82,82,82,82,82,82,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84, +84,84,84,84,84,84,84,84,84,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85, +85,85,85,85,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86, +86,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88, +88,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89, +89,89,89,89,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90, +90,90,90,90,90,90,90,90,90,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92, +92,92,92,92,92,92,92,92,92,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93, +93,93,93,93,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94, +94,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96, +96,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97, +97,97,97,97,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98, +98,98,98,98,98,98,98,98,98,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, +100,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, +101,101,101,101,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, +102,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104, +104,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105, +105,105,105,105,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106, +106,106,106,106,106,106,106,106,106,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, +108,108,108,108,108,108,108,108,108,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, +114,114,114,114,114,114,114,114,114,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +116,116,116,116,116,116,116,116,116,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, +117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118, +118,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121, +121,121,121,121,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, +122,122,122,122,122,122,122,122,122,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, +124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, +125,125,125,125,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, +126,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, +128,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, +129,129,129,129,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130, +130,130,130,130,130,130,130,130,130,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, +132,132,132,132,132,132,132,132,132,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, +133,133,133,133,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134, +134,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136, +136,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137, +137,137,137,137,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138, +138,138,138,138,138,138,138,138,138,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, +140,140,140,140,140,140,140,140,140,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, +141,141,141,141,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, +142,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, +144,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, +145,145,145,145,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, +146,146,146,146,146,146,146,146,146,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, +148,148,148,148,148,148,148,148,148,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, +149,149,149,149,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150, +150,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152, +152,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153, +153,153,153,153,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, +156,156,156,156,156,156,156,156,156,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, +157,157,157,157,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, +158,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160, +160,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, +161,161,161,161,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162, +162,162,162,162,162,162,162,162,162,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, +164,164,164,164,164,164,164,164,164,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, +165,165,165,165,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166, +166,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, +168,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169, +169,169,169,169,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170, +170,170,170,170,170,170,170,170,170,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, +172,172,172,172,172,172,172,172,172,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, +173,173,173,173,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174, +174,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +176,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, +177,177,177,177,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178, +178,178,178,178,178,178,178,178,178,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, +180,180,180,180,180,180,180,180,180,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, +181,181,181,181,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, +182,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184, +184,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185, +185,185,185,185,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186, +186,186,186,186,186,186,186,186,186,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, +188,188,188,188,188,188,188,188,188,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, +189,189,189,189,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +190,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, +192,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +193,193,193,193,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194, +194,194,194,194,194,194,194,194,194,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, +196,196,196,196,196,196,196,196,196,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, +197,197,197,197,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, +198,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200, +200,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +201,201,201,201,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, +204,204,204,204,204,204,204,204,204,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, +205,205,205,205,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, +208,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, +209,209,209,209,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210, +210,210,210,210,210,210,210,210,210,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, +213,213,213,213,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, +214,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, +216,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +217,217,217,217,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, +218,218,218,218,218,218,218,218,218,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, +220,220,220,220,220,220,220,220,220,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, +221,221,221,221,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +222,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226, +226,226,226,226,226,226,226,226,226,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, +228,228,228,228,228,228,228,228,228,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, +229,229,229,229,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, +230,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232, +232,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +233,233,233,233,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, +234,234,234,234,234,234,234,234,234,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, +237,237,237,237,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, +238,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, +240,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, +241,241,241,241,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +242,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, +244,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246, +246,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, +248,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, +250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 +}; diff --git a/core/multimedia/opieplayer/libflash/swf.h b/core/multimedia/opieplayer/libflash/swf.h new file mode 100644 index 0000000..5f5e4f7 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/swf.h @@ -0,0 +1,229 @@ +#ifndef _SWF_H_ +#define _SWF_H_ + +#include +#include +#include +#include +#include +#include + +#ifdef DUMP +#include "bitstream.h" +#endif + +#include "flash.h" + +extern int debug; + +// Global Types +typedef unsigned long U32, *P_U32, **PP_U32; +typedef signed long S32, *P_S32, **PP_S32; +typedef unsigned short U16, *P_U16, **PP_U16; +typedef signed short S16, *P_S16, **PP_S16; +typedef unsigned char U8, *P_U8, **PP_U8; +typedef signed char S8, *P_S8, **PP_S8; +typedef signed long SFIXED, *P_SFIXED; +typedef signed long SCOORD, *P_SCOORD; +typedef unsigned long BOOL; + +#define ZOOM(v,f) ((v)/(f)) + +#include "matrix.h" +#include "cxform.h" +#include "rect.h" + +#include +#define ST struct timeval t1,t2; +#define START gettimeofday(&t1,0) +#define STOP(msg) gettimeofday(&t2,0); printf("%s Delta = %d ms\n", msg, (t2.tv_sec-t1.tv_sec)*1000+(t2.tv_usec-t1.tv_usec)/1000); fflush(stdout); + +// Start Sound Flags +enum { + soundHasInPoint = 0x01, + soundHasOutPoint = 0x02, + soundHasLoops = 0x04, + soundHasEnvelope = 0x08 + + // the upper 4 bits are reserved for synchronization flags +}; + +// Flags for Sound Format +enum SounfFlags { + soundIsStereo = 0x01, + soundIs16bit = 0x02, + soundIsADPCMCompressed = 0x10 +}; + +// Flags for defining Button States +enum ButtonState { + stateHitTest = 0x08, + stateDown = 0x04, + stateOver = 0x02, + stateUp = 0x01 +}; + +// Actions +enum Action { + // Internal actions + ActionRefresh = 0x00, + ActionPlaySound = 0x01, + // Normal actions + ActionGotoFrame = 0x81, + ActionGetURL = 0x83, + ActionNextFrame = 0x04, + ActionPrevFrame = 0x05, + ActionPlay = 0x06, + ActionStop = 0x07, + ActionToggleQuality = 0x08, + ActionStopSounds = 0x09, + ActionWaitForFrame = 0x8a, + ActionSetTarget = 0x8b, + ActionGoToLabel = 0x8c +}; + +class Sound; + +struct ActionRecord { + Action action; + + // GotoFrame & WaitForFrame + long frameIndex; + + // GetURL + char *url; + char *target; + + // GotoLabel + char *frameLabel; + + // WaitForFrame + long skipCount; + + // Sound + Sound *sound; + + struct ActionRecord *next; + + ActionRecord() { + frameLabel = 0; + url = 0; + target = 0; + sound = 0; + }; + + ~ActionRecord() { + if (frameLabel) free(frameLabel); + if (url) free(url); + if (target) free(target); + }; +}; + +enum FontFlags { + fontUnicode = 0x20, + fontShiftJIS = 0x10, + fontANSI = 0x08, + fontItalic = 0x04, + fontBold = 0x02, + fontWideCodes = 0x01 +}; + +enum TextFlags { + isTextControl = 0x80, + + textIsLarge = 0x70, + textHasFont = 0x08, + textHasColor = 0x04, + textHasYOffset= 0x02, + textHasXOffset= 0x01 +}; + +#ifndef NULL +#define NULL 0 +#endif + +// Tag values that represent actions or data in a Flash script. +enum +{ + stagEnd = 0, + stagShowFrame = 1, + stagDefineShape = 2, + stagFreeCharacter = 3, + stagPlaceObject = 4, + stagRemoveObject = 5, + stagDefineBits = 6, + stagDefineButton = 7, + stagJPEGTables = 8, + stagSetBackgroundColor = 9, + stagDefineFont = 10, + stagDefineText = 11, + stagDoAction = 12, + stagDefineFontInfo = 13, + stagDefineSound = 14, // Event sound tags. + stagStartSound = 15, + stagStopSound = 16, + stagDefineButtonSound = 17, + stagSoundStreamHead = 18, + stagSoundStreamBlock = 19, + stagDefineBitsLossless = 20, // A bitmap using lossless zlib compression. + stagDefineBitsJPEG2 = 21, // A bitmap using an internal JPEG compression table. + stagDefineShape2 = 22, + stagDefineButtonCxform = 23, + stagProtect = 24, // This file should not be importable for editing. + + // These are the new tags for Flash 3. + stagPlaceObject2 = 26, // The new style place w/ alpha color transform and name. + stagRemoveObject2 = 28, // A more compact remove object that omits the character tag (just depth). + stagDefineShape3 = 32, // A shape V3 includes alpha values. + stagDefineText2 = 33, // A text V2 includes alpha values. + stagDefineButton2 = 34, // A button V2 includes color transform, alpha and multiple actions + stagDefineBitsJPEG3 = 35, // A JPEG bitmap with alpha info. + stagDefineBitsLossless2 = 36, // A lossless bitmap with alpha info. + stagDefineSprite = 39, // Define a sequence of tags that describe the behavior of a sprite. + stagNameCharacter = 40, // Name a character definition, character id and a string, (used for buttons, bitmaps, sprites and sounds). + stagFrameLabel = 43, // A string label for the current frame. + stagSoundStreamHead2 = 45, // For lossless streaming sound, should not have needed this... + stagDefineMorphShape = 46, // A morph shape definition + stagDefineFont2 = 48, + + notEnoughData = 0xffff, // Special code +}; + +#ifndef false +#define false 0 +#endif +#ifndef true +#define true 1 +#endif + +extern int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb; + +typedef void (*ScanLineFunc)(void *id, long y, long start, long end); + +class Bitmap; +struct FlashMovie; + +extern "C" { +#include "jpeglib.h" +}; +extern "C" { +//#include "zlib.h" +#include "../src/3rdparty/zlib/zlib.h" +}; + +#include "graphic.h" +#include "character.h" +#include "bitmap.h" +#include "shape.h" +#include "displaylist.h" +#include "sound.h" +#include "button.h" +#include "font.h" +#include "text.h" +#include "adpcm.h" +#include "program.h" +#include "sprite.h" +#include "script.h" +#include "movie.h" + +#endif /* _SWF_H_ */ diff --git a/core/multimedia/opieplayer/libflash/text.cc b/core/multimedia/opieplayer/libflash/text.cc new file mode 100644 index 0000000..1b6cb5e --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/text.cc @@ -0,0 +1,246 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +// Author : Olivier Debon +// + +#include "swf.h" + +#ifdef RCSID +static char *rcsid = "$Id$"; +#endif + +Text::Text(long id) : Character(TextType, id) +{ + textRecords = 0; +} + +Text::~Text() +{ + TextRecord *cur,*del; + + for(cur = textRecords; cur;) + { + del = cur; + cur = cur->next; + delete del; + } +} + +void +Text::setTextBoundary(Rect rect) +{ + boundary = rect; +} + +void +Text::setTextMatrix(Matrix m) +{ + textMatrix = m; +} + +void +Text::addTextRecord(TextRecord *tr) +{ + SwfFont *font = 0; + long n; + + tr->next = 0; + + if (textRecords == 0) { + textRecords = tr; + font = tr->font; + } else { + TextRecord *current; + long fontHeight = 0; + + for(current = textRecords; current->next; current = current->next) { + if (current->flags & textHasFont) { + font = current->font; + fontHeight = current->fontHeight; + } + } + + current->next = tr; + if (current->flags & textHasFont) { + font = current->font; + fontHeight = current->fontHeight; + } + + if (tr->flags & textHasFont) { + font = tr->font; + } else { + tr->font = font; + tr->fontHeight = fontHeight; + } + } + + if (tr->nbGlyphs) { + for(n=0; n < tr->nbGlyphs; n++) { + tr->glyphs[n].code = font->getGlyphCode(tr->glyphs[n].index); + } + } +} + +int +Text::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform) +{ + return doText(gd, matrix, cxform, ShapeDraw, NULL, NULL); +} + +void +Text::getRegion(GraphicDevice *gd, Matrix *matrix, + void *id, ScanLineFunc scan_line_func) +{ + doText(gd, matrix, 0, ShapeGetRegion, id, scan_line_func); +} + +void +Text::getBoundingBox(Rect *bb, DisplayListEntry *e) +{ + *bb = boundary; +} + +TextRecord * +Text::getTextRecords() +{ + return textRecords; +} + +int +Text::doText(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ShapeAction action, + void *id, ScanLineFunc scan_line_func) +{ + TextRecord *tr; + long x,y; // Current position + SwfFont *font = 0; // Current font + long fontHeight; + Matrix tmat,fmat; + long g; + + x = y = 0; + fontHeight = 0; + + // Compute final text matrix + tmat = (*matrix) * textMatrix; + + for(tr = textRecords; tr; tr = tr ->next) + { + if (tr->flags & isTextControl) { + if (tr->flags & textHasXOffset) { + x = tr->xOffset; + } + if (tr->flags & textHasYOffset) { + y = tr->yOffset; + } + if (tr->flags & textHasColor) { + if (action == ShapeDraw) { + if (cxform) { + gd->setForegroundColor(cxform->getColor(tr->color)); + } else { + gd->setForegroundColor(tr->color); + } + } + } + } + + font = tr->font; + fontHeight = tr->fontHeight; + // Update font matrix + fmat.a = fontHeight/1000.0; + fmat.d = fontHeight/1000.0; + + assert(font != 0); + for (g = 0; g < tr->nbGlyphs; g++) + { + Shape *shape; + Matrix cmat; + + shape = font->getGlyph( tr->glyphs[g].index ); + +#ifdef PRINT + printf("%c", font->getGlyphCode(tr->glyphs[g].index)); +#endif + + // Update font matrix + fmat.tx = x; + fmat.ty = y; + + // Compute Character matrix + cmat = tmat * fmat; + + if (action == ShapeDraw) { + shape->execute(gd, &cmat, cxform); + } else { + shape->getRegion(gd, &cmat, id, scan_line_func); + } + + // Advance + x += tr->glyphs[g].xAdvance; + } +#ifdef PRINT + printf("\n"); +#endif + } + + if (gd->showMore) { + tmat = (*gd->adjust) * (*matrix); + + long x1,x2,y1,y2; + + x1 = boundary.xmin; + y1 = boundary.ymin; + x2 = boundary.xmax; + y2 = boundary.ymax; + gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),FRAC); + gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),FRAC); + gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),FRAC); + gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),FRAC); + } + + return 0; +} + +////////// TextRecord Methods +TextRecord::TextRecord() { + flags = (TextFlags)0; + font = 0; + fontHeight = 0; + nbGlyphs = 0; + glyphs = 0; + xOffset = 0; + yOffset = 0; +} + +TextRecord::~TextRecord() { + if (nbGlyphs) delete glyphs; +} + +char * +TextRecord::getText() { + static char text[256]; + long g; + + for(g=0; g < nbGlyphs; g++) { + text[g] = glyphs[g].code; + } + text[g] = 0; + + return text; +} diff --git a/core/multimedia/opieplayer/libflash/text.h b/core/multimedia/opieplayer/libflash/text.h new file mode 100644 index 0000000..1ba7b74 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/text.h @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////// +// Flash Plugin and Player +// Copyright (C) 1998,1999 Olivier Debon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +/////////////////////////////////////////////////////////////// +#ifndef _TEXT_H_ +#define _TEXT_H_ + +struct Glyph { + long index; + long xAdvance; + long code; // Ascii code +}; + +struct TextRecord { + + // Normal text record + Glyph *glyphs; + long nbGlyphs; + + // Control text record + TextFlags flags; + SwfFont *font; + long fontHeight; + Color color; + long xOffset; + long yOffset; + + TextRecord *next; + + TextRecord(); + ~TextRecord(); + + char *getText(); +}; + +class Text : public Character { + + Rect boundary; + Matrix textMatrix; + TextRecord *textRecords; // List + +public: + Text(long id); + ~Text(); + + void setTextBoundary(Rect rect); + void setTextMatrix(Matrix m); + void addTextRecord(TextRecord *tr); + int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform); + void getRegion(GraphicDevice *gd, Matrix *matrix, + void *id, ScanLineFunc scan_line_func); + int doText(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ShapeAction action, + void *id, ScanLineFunc scan_line_func); + void getBoundingBox(Rect *bb, DisplayListEntry *e); + TextRecord *getTextRecords(); + +#ifdef DUMP + void dump(BitStream *bs); +#endif +}; + +#endif /* _TEXT_H_ */ -- cgit v0.9.0.2