<?php
/*
* OekakiApplet
* Version 1.0 Beta
* Created by sk89q
* http://www.therisenrealm.com
* http://www.keiichianimeforever.com
*
* Copyright (c) 2004, sk89q
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of sk89q nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
class OekakiInput
{
function autodetermine( $data )
{
switch( substr( $data, 0, 1 ) )
{
case 'S':
return 'shipainter';
case 'P':
return 'paintbbs';
default:
return 'oekakibbs';
}
}
function autoprocess( $applet, $data, &$anim_ext, &$print_ok, &$print_error_prefix, &$response_mimetype, &$error )
{
$response_mimetype = 'text/plain';
switch( strtolower( $applet ) )
{
case 'shi':
case 'shipro':
case 'shipaint':
case 'shipaintpro':
case 'shipainter':
case 'shipainterpro':
{
$anim_ext = 'pch';
$print_ok = TRUE;
return $this->shipainter( $data, $error );
break;
}
case 'paint':
case 'paintbbs':
{
$anim_ext = 'pch';
$print_ok = TRUE;
$print_error_prefix = TRUE;
return $this->paintbbs( $data, $error );
break;
}
case 'oekaki':
case 'oekakibbs':
{
$anim_ext = 'oeb';
$print_ok = FALSE;
$print_error_prefix = FALSE;
return $this->oekakibbs( $data, $error );
break;
}
default:
{
$error = 'INVALID_APPLET';
return FALSE;
}
}
}
function shipainter( $data, &$error )
{
// Same data format
return $this->_shibbs( $data, $error, 'S' );
}
function paintbbs( $data, &$error )
{
// Same data format
return $this->_shibbs( $data, $error, 'P' );
}
function _shibbs( $data, &$error, $data_string )
{
$error = '';
$header = array(
'length' => 0,
'data' => array(),
);
$image = array(
'length' => 0,
'data' => '',
);
$animation = array(
'length' => 0,
'data' => '',
);
$thumbnail = array(
'length' => 0,
'data' => '',
);
$save_id = basename( $_GET['saveid'] );
do
{
//-------------------------------------
// SOME CHECKING
//-------------------------------------
if( empty( $data ) )
{
$error = 'NO_IMAGE_DATA';
break;
}
if( substr( $data, 0, 1 ) != $data_string )
{
$error = 'INVALID_DATA';
break;
}
//-------------------------------------
// PARSE HEADER
//-------------------------------------
$header['length'] = intval( substr( $data, 1, 8 ) );
$tmp_data['raw'] = substr( $data, 9, $header['length'] );
$tmp_data['lines'] = explode( ';', $tmp_data['raw'] );
foreach( $tmp_data['lines'] as $line )
{
$line = explode( '=', $line, 2 );
if( $line[0] )
{
$header['data'][] = $line[1];
}
}
unset( $tmp_data );
//-------------------------------------
// PARSE IMAGE DATA
// Just gets the data after the header
//-------------------------------------
$image['length'] = intval( substr( $data, $header['length'] + 9, 8 ) );
$image['data'] = substr( $data, $header['length'] + 19, $image['length'] );
//-------------------------------------
// PARSE ANIMATION DATA
// Just gets the data after the header and image
//-------------------------------------
$animation['length'] = intval( substr( $data, $header['length'] + $image['length'] + 19, 8 ) );
$animation['data'] = substr( $data, $header['length'] + $image['length'] + 27, $animation['length'] );
//-------------------------------------
// PARSE THUMBNAIL DATA
// Just gets the data after the header, image and animation
//-------------------------------------
$thumbnail['length'] = intval( substr( $data, $header['length'] + $image['length'] + $animation['length'] + 27, 8 ) );
$thumbnail['data'] = substr( $data, $header['length'] + $image['length'] + $animation['length'] + 35, $thumbnail['length'] );
//-------------------------------------
// EVEN MORE CHECKING
//-------------------------------------
if( empty( $image['data'] ) )
{
$error = 'NO_IMAGE_DATA';
break;
}
}
while( FALSE );
if( $error )
{
return FALSE;
}
else
{
return array(
'IMAGE' => $image['data'],
'ANIMATION' => $animation['data'],
'THUMBNAIL' => $thumbnail['data'],
);
}
}
function oekakibbs( $data, &$error )
{
$error = '';
$header = array(
'length' => 0,
'data' => array(),
);
$image = array(
'length' => 0,
'data' => '',
);
$animation = array(
'length' => 0,
'data' => '',
);
$save_id = basename( $_GET['saveid'] );
do
{
//-------------------------------------
// SOME CHECKING
//-------------------------------------
if( empty( $data ) )
{
$error = 'NO_IMAGE_DATA';
break;
}
//-------------------------------------
// PARSE DATA
//-------------------------------------
$start_offset = 0;
$end_offset = TRUE;
while( $end_offset )
{
// This is how it goes:
// 1. Seek to next Content-type
// 2. Read content type
// 3. Seek to end of header for this data block
// 4. Read data
// 5. Stop at next Content-type or EOF
$start_offset = strpos( $data, 'Content-type:', $start_offset ) + strlen( 'Content-type:' );
$content_type = substr( $data, $start_offset, strpos( $data, "\r", $start_offset ) - $start_offset );
$start_offset += strlen( $content_type ) + 4;
//-------------------------------------
// READ DATA
//-------------------------------------
if( FALSE === ( $end_offset = strpos( $data, 'Content-type:', $start_offset ) ) )
{
$read_data = substr( $data, $start_offset );
}
else
{
$read_data = substr( $data, $start_offset, $end_offset - $start_offset );
}
//-------------------------------------
// PARSE DATA
//-------------------------------------
if( $content_type == 'image/0' || $content_type == 'image/1' )
{
$image['data'] = $read_data;
}
elseif( $content_type == 'animation' || $content_type == 'animation' )
{
$animation['data'] = $read_data;
}
$start_offset = $end_offset;
}
//-------------------------------------
// EVEN MORE CHECKING
//-------------------------------------
if( empty( $image['data'] ) )
{
$error = 'NO_IMAGE_DATA';
break;
}
}
while( FALSE );
if( $error )
{
return FALSE;
}
else
{
return array(
'IMAGE' => $image['data'],
'ANIMATION' => $animation['data'],
);
}
}
}
?>