Compare commits

..

4 Commits

Author SHA1 Message Date
7bef98a33a update zstd-jnilib to latest
and provide in fetch_dependencies information of latest

Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-02 20:21:31 +01:00
fcda589742 cleanup remove samples 2025-11-02 18:30:07 +01:00
bce0e160d8 don't build build.xml, maintain it manualy
remove antify.sh and related builx.xml target makefile

Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-02 18:10:21 +01:00
36e58808d5 don't depend on sharedrawweb
use directly sharedrawweb java code here

Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-02 18:04:02 +01:00
38 changed files with 1416 additions and 2428261 deletions

View File

@@ -4,7 +4,7 @@ DISTJAR=$(DISTPREFIX)-$(PROJECT_VERSION).jar
JAVAC=javac JAVAC=javac
JAR=jar JAR=jar
all: build.xml dist/lib/$(DISTJAR) all: dist/lib/$(DISTJAR)
getname: getname:
@echo dist/lib/$(DISTJAR) @echo dist/lib/$(DISTJAR)
@@ -18,9 +18,6 @@ dist:
dist/lib/$(DISTJAR): dist dist/lib/$(DISTJAR): dist
ant dist ant dist
build.xml:
./antify.sh >$@
clean: clean:
cd java; make clean cd java; make clean
rm -f dist/lib/$(DISTPREFIX)*.jar rm -f dist/lib/$(DISTPREFIX)*.jar
@@ -41,7 +38,7 @@ deb/%:
./debianize.sh create $@ ./debianize.sh create $@
debian/compat: debian/compat:
echo "7" >$@ echo "10" >$@
debian/%: debian/%:
./debianize.sh create $@ >$@ ./debianize.sh create $@ >$@

View File

@@ -6,7 +6,7 @@ JAVAC=javac
JAR=jar JAR=jar
RHINO_VER=1_7R5 RHINO_VER=1_7R5
all: build.xml dist/lib/$(DISTJAR) all: dist/lib/$(DISTJAR)
getname: getname:
@echo dist/lib/$(DISTJAR) @echo dist/lib/$(DISTJAR)
@@ -17,11 +17,7 @@ dist:
dist/lib/$(DISTJAR): dist dist/lib/$(DISTJAR): dist
ant dist ant dist
build.xml:
./antify.sh >$@
clean: clean:
rm -f build.xml
rm -f dist/lib/$(DISTPREFIX)*.jar rm -f dist/lib/$(DISTPREFIX)*.jar
rm -rf build rm -rf build
cd java; make clean cd java; make clean
@@ -41,13 +37,13 @@ deb/%:
./debianize.sh create $@ ./debianize.sh create $@
debian/compat: debian/compat:
echo "7" >$@ echo "10" >$@
debian/%: debian/%:
./debianize.sh create $@ >$@ ./debianize.sh create $@ >$@
deb: debian debian/rules debian/control debian/compat debian/changelog deb/javadoc deb/jlibs deb: debian debian/rules debian/control debian/compat debian/changelog deb/javadoc deb/jlibs deb/format
dpkg-buildpackage -uc -us ./buildsourcetree.sh
/usr/bin/emacs: /usr/bin/emacs:
sudo apt-get install emacs sudo apt-get install emacs

View File

@@ -1,12 +0,0 @@
java/
java sources
java/org/artisanlogiciel/games
java sources for package org.artisanlogiciel.games respect of java directory naming convention of files
java/org/artisanlogiciel/games/Main.java
Main Java entry point for this program

View File

@@ -1,92 +0,0 @@
#!/bin/bash
#
# Generates to stdout an ant project build.xml content using some parameters from project_params
#
# this is used by 4java.makefile for build.xml target
usage()
{
head -n 4 $0
}
PROJECT_PARAMS=./project_params
if [[ -f $PROJECT_PARAMS ]]
then
source $PROJECT_PARAMS
else
echo "[ERROR] missing $PROJECT_PARAMS " >&2
usage
exit 1
fi
# TODO reuse internal tsamp ${DSTAMP} ( after review i do't recall what is wanted to do here )
cat <<EOF
<project name="$project_name" default="$project_default" basedir="$project_basedir">
<description>
$project_name build
autogenerated build file by $0 script
</description>
<!-- set global properties for this build -->
<property name="src" location="java"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<!-- Fill me please / todo
<property name="artgraphicslib" value="artgaphics-0.1.0"/>
<property name="distversion" value="1.0"/>
-->
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="\${build}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from \${src} into \${build} -->
EOF
if [[ -z $java_target ]]
then
echo ' <javac srcdir="${src}" destdir="${build}">'
else
echo " <javac target=\"$java_target\" source=\"$java_target\" srcdir=\"\${src}\" destdir=\"\${build}\"><compilerarg value=\"-Xlint:-options\"/>"
fi
echo "<!-- suggestion "
excludes="org/artisanlogiciel/games/javafx/*"
for exclude in "$excludes"
do
echo " <exclude name=\"$exclude\"/>"
done
echo "-->"
echo " </javac>"
cat <<EOF
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="\${dist}/lib"/>
<!-- Put everything in \${build} into the ${project_name}-${project_version}.jar file ( \${DSTAMP} not used yet )-->
<jar jarfile="\${dist}/lib/${project_name}-${project_version}.jar" basedir="\${build}">
<manifest>
<attribute name="Main-Class" value="$project_mainclass"/>
<!-- suggestion
<attribute name="Class-Path" value="\${artgraphicslib}.jar"/>
-->
</manifest>
</jar>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the \${build} and \${dist} directory trees -->
<delete dir="\${build}"/>
<delete dir="\${dist}"/>
</target>
</project>
EOF

View File

@@ -13,8 +13,7 @@
<!-- Fill me please / todo <!-- Fill me please / todo
see fetch_dependencies see fetch_dependencies
--> -->
<property name="artgraphicslib" value="artgaphics-0.2.0"/> <property name="zstd-jnilib" value="zstd-jni-1.5.7-6"/>
<property name="zstd-jnilib" value="zstd-jni-1.5.2-2"/>
<target name="gather_project_params"> <target name="gather_project_params">
<!-- original source parameter is in project_params project_version --> <!-- original source parameter is in project_params project_version -->
<loadfile property="distversion" srcfile="${basedir}/project_params"> <loadfile property="distversion" srcfile="${basedir}/project_params">
@@ -41,7 +40,7 @@
<target name="compile" depends="init" <target name="compile" depends="init"
description="compile the source " > description="compile the source " >
<!-- Compile the java code from ${src} into ${build} --> <!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}" includeantruntime="false" classpath="libs/${artgraphicslib}.jar:libs/${zstd-jnilib}.jar"> <javac srcdir="${src}" destdir="${build}" includeantruntime="false" classpath="libs/${zstd-jnilib}.jar">
<exclude name="org/artisanlogiciel/games/javafx/*"/> <exclude name="org/artisanlogiciel/games/javafx/*"/>
<compilerarg value="-Xlint:deprecation,unchecked" /> <compilerarg value="-Xlint:deprecation,unchecked" />
</javac> </javac>

View File

@@ -10,6 +10,12 @@ toolsdir=$(pwd)
source metascript.sh source metascript.sh
popd >/dev/null popd >/dev/null
usage() {
cat <<EOF
$0 use_jackson|use_zstd|use_artgraphic
EOF
}
fetch_jackson_databind() fetch_jackson_databind()
{ {
lib_jackson_databind=jackson-databind-${libversion_jackson_databind}.jar lib_jackson_databind=jackson-databind-${libversion_jackson_databind}.jar
@@ -24,17 +30,27 @@ fetch_jackson_databind()
fetch_zstd-jni() fetch_zstd-jni()
{ {
# echo "compiled from https://github.com/luben/zstd-jni commit 54d3d50c16d96bd8a30e2d4c0a9648001a52d6f9" # echo "compiled from https://github.com/luben/zstd-jni commit 54d3d50c16d96bd8a30e2d4c0a9648001a52d6f9"
# had to hack through jar generation ... # had to hack through jar generation ...
# cp ~/artisanlogiciel/ext_projects/java/zstd-jni/target/zstd-jni-1.5.2-2.jar . # cp ~/artisanlogiciel/ext_projects/java/zstd-jni/target/zstd-jni-1.5.2-2.jar .
maven_repo=https://repo1.maven.org/maven2/
package_path=com/github/luben/zstd-jni/
# https://repo1.maven.org/maven2/maven-metadata.xml
latest=$(curl -s ${maven_repo}${package_path}maven-metadata.xml | xmllint --xpath 'string(metadata/versioning/latest)' -)
log_info "latest version : $latest"
zstdjni=$(xmllint --xpath 'string(/project/property[@name="zstd-jnilib"]/@value)' build.xml)
if [[ -n $zstdjni ]]
then
$defer pushd libs $defer pushd libs
$metarun wget https://repo1.maven.org/maven2/com/github/luben/zstd-jni/${libversion_zstdjni}/zstd-jni-${libversion_zstdjni}.jar libversion_zstdjni=${zstdjni/zstd-jni-}
$metarun curl ${maven_repo}${package_path}${libversion_zstdjni}/${zstdjni}.jar -o ${zstdjni}.jar
$defer popd $defer popd
else
log_error 'no /project/property[@name="zstd-jnilib"]/@value) found in build.xml'
fi
} }
# HARDCODED START # HARDCODED START
libversion_zstdjni=1.5.2-2
libversion_jackson_databind=2.12.0 libversion_jackson_databind=2.12.0
sharedrawweb_git_url="https://framagit.org/artlog/sharedrawweb.git" sharedrawweb_git_url="https://framagit.org/artlog/sharedrawweb.git"
libversion_artgaphic=0.2.0 libversion_artgaphic=0.2.0
@@ -52,7 +68,10 @@ do
use_jackson=$1 use_jackson=$1
;; ;;
use_zstd) use_zstd)
use_zstd=1 use_zstd=$1
;;
use_artgraphic)
use_artgraphic=$1
;; ;;
*) *)
parsemetaarg "$1" parsemetaarg "$1"
@@ -62,21 +81,20 @@ do
done done
if [[ ! -d sharedrawweb ]]
then
log_error "expected a sharedrawweb project parent ( for exports ). Please clone related project."
log_info "git clone $sharedrawweb_git_url sharedrawweb"
fi
if [[ ! -d libs ]] if [[ ! -d libs ]]
then then
$metarun mkdir libs $metarun mkdir libs
fi fi
libversion_artgaphic=0.2.0 if [[ -n $user_artgraphic ]]
lib_artgaphic=artgaphics-${libversion_artgaphic}.jar
if [[ ! -e libs/$lib_artgaphic ]]
then then
if [[ ! -d sharedrawweb ]]
then
log_error "expected a sharedrawweb project parent ( for exports ). Please clone related project."
log_info "git clone $sharedrawweb_git_url sharedrawweb"
fi
if [[ ! -e libs/$lib_artgaphic ]]
then
lib_artgaphic_source_file=sharedrawweb/dist/lib/$lib_artgaphic lib_artgaphic_source_file=sharedrawweb/dist/lib/$lib_artgaphic
if [[ -f $lib_artgaphic_source_file ]] if [[ -f $lib_artgaphic_source_file ]]
then then
@@ -86,6 +104,7 @@ then
log_error "Missing $lib_artgaphic_source_file" log_error "Missing $lib_artgaphic_source_file"
log_info "It is required to build sharedrawweb project first" log_info "It is required to build sharedrawweb project first"
fi fi
fi
fi fi
if [[ -n $use_jackson ]] if [[ -n $use_jackson ]]

View File

@@ -0,0 +1,92 @@
package org.artisanlogiciel.compression;
import java.io.DataInputStream;
import java.io.OutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.artisanlogiciel.graphics.SvgWriter;
import org.artisanlogiciel.graphics.Drawing;
/**
* Very simple utility to convert from .imc to svg.
*
* TODO : could be more clever and not load full image into memory to save it afterwards ( for very small embedded systems ).
*/
public class Main
{
Drawing mLocalImage;
public static void main(String[] args) {
Main m = new Main();
if ( args.length > 1 )
{
m.loadExpanded(args[0]);
try {
File out = new File(args[1]);
if (out.exists())
{
System.err.println("File already exists" + out + " Not overriding it");
}
else
{
//m.saveSvg(new DataOutputStream(new FileOutputStream(out)));
FileOutputStream fout = new FileOutputStream(out);
m.saveSvg(fout);
fout.flush();
fout.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
else
{
System.out.println("Very simple utility to convert from .imc to svg.");
System.out.println("first argument is compressed file, second is svg output file (should not already exist)");
}
}
public void saveSvg(OutputStream s)
throws IOException
{
SvgWriter writer = new SvgWriter(mLocalImage.getLines());
writer.writeTo(s);
}
public void saveKompressed( String ref) {
try {
FileOutputStream fi = new FileOutputStream( ref);
mLocalImage.saveLinesKompressed( new DataOutputStream( fi));
}
catch( java.io.FileNotFoundException fnfe)
{
fnfe.printStackTrace(System.err);
}
catch ( java.io.IOException ioe) {
ioe.printStackTrace(System.err);
}
}
public void loadExpanded( String ref) {
try {
FileInputStream fi = new FileInputStream( ref);
mLocalImage = new Drawing();
mLocalImage.loadLinesExpanded( new DataInputStream( fi));
}
catch( java.io.FileNotFoundException fnfe) {
fnfe.printStackTrace(System.err);
}
catch ( java.io.IOException ioe) {
ioe.printStackTrace(System.err);
}
}
}

View File

@@ -0,0 +1,146 @@
/*
This file is part of ShareDrawWeb.
ShareDrawWeb 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.
ShareDrawWeb 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 ShareDrawWeb; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.artisanlogiciel.compression.graphics;
/*
simple class to read bitfields
@see BitFieldWriter
@author Philippe Lhardy
*/
import java.io.*;
class BitFieldReader {
// size of nextWord
final int dataSize = 32;
/* offset of next bit to be read in current word
should ensure bitOffset < dataSize
*/
private int bitOffset = 0;
/* word used waiting to be fully read
dataSize is bit size of currentWord
currentWord is part of word read that begins at bitOffset.
*/
private int currentWord = 0;
private DataInputStream inputStream;
/* value returned is an int between 0 and 2^bits-1 */
public int read( int bits) throws java.io.IOException {
int field = 0;
int head = 0;
// a new word is needed
if ( bitOffset == 0 ) {
nextWord();
}
// if more bits needed that word currently used.
if ( bits + bitOffset > dataSize) {
// warning recursive call ( not terminal )
int bitsize = dataSize - bitOffset;
head = read( dataSize - bitOffset);
// current word had entirely been read, need a new one
// don't do that... nextWord() will be done by next read...
field = read( bits - bitsize);
// reconstruct all
// more significant bits in first word, least in last
field = field | ( head << (bits - bitsize));
}
else {
// terminal part do the job
if ( bits == dataSize) {
// special case to keep sign
field = currentWord;
currentWord = 0;
bitOffset = 0;
}
else {
field = ( currentWord >> ( dataSize - bits) )
& ( 0x7fffffff >> ( dataSize - 1 - bits) );
// bits are read then remove them from currentWord
currentWord <<= bits;
bitOffset = ( bitOffset + bits ) % dataSize;
/*
System.out.println( "size " + Integer.toString(bits)
+ " value " + Integer.toString(field)
+ " offset " + Integer.toString(bitOffset)
+ " currentWord " + Integer.toString( currentWord)
);
*/
}
}
return field;
}
private int getInt( byte[] pBytes)
{
long field = 0;
field = pBytes[0]<<24 | pBytes[1]<<16 | pBytes[2]<<8 | pBytes[3];
return (int) field;
}
/**
* doesn't work correctly as readInt
*/
private int readInt()
throws IOException
{
byte bytes[]=new byte[4];
int nr=0;
int index = 0;
/* read at least 4 bytes */
while ( ( nr != -1) && ( index < 4 ) )
{
nr = inputStream.read( bytes, index, 4 - index);
index +=nr;
}
return getInt( bytes);
}
private void nextWord() throws java.io.IOException {
// read next word
// currentWord = readInt();
currentWord= inputStream.readInt();
bitOffset = 0;
}
/*
go to next entire word.
*/
public void padToWord() throws java.io.IOException {
if ( bitOffset != 0) {
nextWord();
}
}
/* set InputStream */
public void setInputStream( InputStream input) {
inputStream = new DataInputStream(input);
}
}

View File

@@ -0,0 +1,125 @@
/*
This file is part of ShareDrawWeb.
ShareDrawWeb 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.
ShareDrawWeb 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 ShareDrawWeb; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.artisanlogiciel.compression.graphics;
/*
simple class to write bitfields
@see BitFieldReader
@author Philippe Lhardy
*/
import java.io.*;
class BitFieldWriter {
// size of nextWord
final int dataSize = 32;
/* bitOffset is number of bits already used in word
should ensure bitOffset < dataSize
*/
private int bitOffset;
/* word used waiting to be filled to be written
dataSize is bit size of nextWord
*/
private int nextWord;
private DataOutputStream outputStream;
public void write( int field, int bits) throws java.io.IOException {
// if more bits needed that word currently used.
if ( bits + bitOffset > dataSize) {
// warning recursive call ( not terminal )
// fill and write current word
int bitsize = dataSize - bitOffset;
int head;
// most significant bits first
// suppress at left least significant bits
head = field >> (bits - bitsize);
write( head, dataSize - bitOffset);
// no need of newWord() previous write already done it
// least significant bits last
field = field & ( 0x7FFFFFFF >> ( bitsize - 1));
write( field, bits - bitsize);
}
else {
if ( bits == dataSize ) {
// special case to keep sign
nextWord = field;
bitOffset = 0;
}
else {
// keep only meaning part of field
field = field & ( 0x7FFFFFFF >> ( dataSize - 1 - bits));
nextWord = nextWord | ( field << ( dataSize - bits - bitOffset));
bitOffset = ( bitOffset + bits ) % dataSize;
}
// a new word is needed
if ( bitOffset == 0 ) {
newWord();
}
}
/*
System.out.println( "nextWord " + Integer.toString( nextWord) + " size "
+ Integer.toString( bits) + " field " + Integer.toString( field));
*/
}
/**
* seems to works correctly as DataOutputStream.writeInt()
*/
private void writeInt( int i)
throws IOException
{
long j = i;
byte bytes[]=new byte[4];
bytes[0] = (byte) ((j & 0xFF000000) >> 24);
bytes[1] = (byte) ((j & 0x00FF0000) >> 16);
bytes[2] = (byte) ((j & 0x0000FF00) >> 8);
bytes[3] = (byte) (j & 0x000000FF);
outputStream.write( bytes, 0, 4);
}
private void newWord() throws java.io.IOException {
// do really write current word;
//writeInt( nextWord);
outputStream.writeInt(nextWord);
// reset nextWord
bitOffset = 0;
nextWord = 0;
}
/*
write all current datas if any
to have a clean word ready.
*/
public void padToWord() throws java.io.IOException {
if ( bitOffset != 0) {
newWord();
}
}
/* set OutputStream */
public void setOutputStream( OutputStream output) {
outputStream = new DataOutputStream(output);
}
}

View File

@@ -0,0 +1,149 @@
/*
This file is part of ShareDrawWeb.
ShareDrawWeb 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.
ShareDrawWeb 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 ShareDrawWeb; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
DrawingLineExpander
decompress a draw line from a stream
main algorithm is to code only delta displacement in littlest possible size.
*/
package org.artisanlogiciel.compression.graphics;
import java.awt.Point;
import java.io.InputStream;
import java.util.ArrayList;
public class DrawLineExpander {
ArrayList<Point> expandedLines;
int currentSize;
int scode[] = {3,6,14,30,64};
final static int SCODE_MAX = 4;
private BitFieldReader fieldReader = null;
public DrawLineExpander() {
expandedLines = new ArrayList<>();
fieldReader = new BitFieldReader();
}
/* create a List of points */
public ArrayList<Point> expand( InputStream input ) throws java.io.IOException {
fieldReader.setInputStream( input);
int point_count = fieldReader.read( 32);
// System.out.println( point_count);
expandedLines.add( readAbs( 64));
for ( int i = 1; i < point_count; i ++ ) {
Point point = readRel();
if ( currentSize == 64 ) {
// absolute
expandedLines.add( point);
}
else {
// relative
Point previous = (Point) expandedLines.get(expandedLines.size()-1);
point.x = point.x + previous.x;
point.y = point.y + previous.y;
expandedLines.add( point);
}
}
return expandedLines;
}
/*
read point with size encoding depending on first bits
*/
private Point readRel() throws java.io.IOException {
int index;
/* 11 : next, 10 : previous ; 0* : same
6 -> 14->30
^ |
| v
3 <- 64
*/
// find index of current size
for ( index = 0; index < SCODE_MAX; index ++) {
if ( scode[index] == currentSize ) break;
}
// read size modifier until it is good one
while ( fieldReader.read(1) != 0 ) {
index = index + ( ( fieldReader.read(1) == 0 ) ? -1 : 1);
// handle circularity
if ( index > SCODE_MAX ) {
index = 0;
}
if ( index < 0 ) {
index = SCODE_MAX;
}
}
return readAbs( scode[index]);
}
/* write given Point with size */
Point readAbs( int size) throws java.io.IOException {
int codeval;
int center, max;
currentSize = size;
Point point = new Point();
if ( size > 32 ) {
point.x = fieldReader.read(32);
point.y = fieldReader.read(32);
}
else {
boolean nocenter=false;
codeval = fieldReader.read( size);
// System.out.println( codeval);
/*
for coding/decoding scheme see
org.artisanlogiciel.graphics.DrawLineKompressor.java
*/
if ( size == 3 ) {
max = 3;
center = 1;
nocenter=true;
}
else {
max = ( 1 << ( size / 2 ) );
center = (max / 2) - 1;
}
// central hole impossible but we don't really care
if ( nocenter )
{
if ( codeval > ( center * max ) ) {
codeval ++;
}
if ( codeval >= ( max * max )) {
System.out.println(
"!!! reserved value for decompression should not occur !!!");
}
}
point.x = ( codeval % max) - center;
point.y = ( codeval / max) - center;
// System.out.println( point.toString());
}
return point;
}
}

View File

@@ -0,0 +1,256 @@
/*
This file is part of ShareDrawWeb.
ShareDrawWeb 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.
ShareDrawWeb 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 ShareDrawWeb; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
DrawingLineKompressor
compress a draw line over a stream
main algorithm is to code only delta displacement in littlest possible size.
*/
package org.artisanlogiciel.compression.graphics;
import java.awt.Point;
import java.io.OutputStream;
import java.util.ArrayList;
public class DrawLineKompressor {
ArrayList<Point> fromLines;
int previousSize;
int scode[] = {3,6,14,30,64};
final static int SCODE_MAX = 4;
private BitFieldWriter fieldWriter = null;
public DrawLineKompressor( ArrayList<Point> lines) {
fromLines = lines;
fieldWriter = new BitFieldWriter();
}
public void kompress( OutputStream output ) throws java.io.IOException {
fieldWriter.setOutputStream( output);
int skipsame=0;
if ( ( fromLines != null) && ( fromLines.size() > 0)) {
Point topoint = null;
for ( int i = 1; i < fromLines.size(); i++) {
Point frompoint = (Point) fromLines.get( i);
if ( ( topoint != null ) && ( topoint.x == frompoint.x ) && ( topoint.y == frompoint.y ) )
{
skipsame ++;
}
topoint=frompoint;
}
if ( skipsame > 0 )
{
System.out.println("[WARNING] lines contains " + skipsame + " duplicates points");
}
}
if ( ( fromLines != null) && ( fromLines.size() > 0)) {
Point frompoint = (Point) fromLines.get(0);
Point point, topoint;
topoint = new Point();
int center, size;
fieldWriter.write( fromLines.size() - skipsame, 32);
writeAbs( frompoint, 64);
for ( int i = 1; i < fromLines.size(); i++) {
point = (Point) fromLines.get( i);
topoint.x = point.x - frompoint.x;
topoint.y = point.y - frompoint.y;
// find wich size to use...
if (( topoint.x == 0 ) && ( topoint.y == 0 ))
{
// ARGH THIS IS INVALID !
System.out.println("[ERROR] (0,0) point is invalid for compression !!!");
continue;
}
if ( (Math.abs( topoint.x) < 2) && (Math.abs(topoint.y) < 2)) {
writeRel( topoint, 3);
}
else {
size = 64;
for ( int index = 1; index < ( SCODE_MAX - 1 ); index ++) {
/* center = ( ( 1 << ( scode[index] / 2 ) ) - 1 ) / 2;
if ( (Math.abs(topoint.x) <= center)
&& (Math.abs(topoint.y) <= center))
{
size = scode[index];
}
*/
// center is biased there are more + than - , ex for 6bits :(x,y) within ( -3,4 ) x (-3,4)
center = 1 << ( ( scode[index] / 2 ) - 1 );
if ( ( topoint.x <= center ) && ( topoint.x > -center )
&& ( topoint.y <= center ) && ( topoint.y > -center ) )
{
size = scode[index];
// always take the smaller size.
break;
}
}
if ( size < 32 ) {
writeRel( topoint, size);
}
else {
// warning absolute
writeRel( point, 64);
}
}
// new frompoint is previous point
frompoint = point;
}
fieldWriter.padToWord();
}
}
/*
compute bits of size
*/
void writeRel( Point point, int size) throws java.io.IOException {
/*
System.out.println( "point " + point.toString());
System.out.println( "size " + Integer.toString( size));
*/
/* 11 : next, 10 : previous ; 0* : same
6 -> 14
^ |
| v
3 <- 64
*/
if ( size != previousSize) {
int cindex, pindex;
// find index of size
for ( cindex = 0; cindex < SCODE_MAX; cindex ++) {
if ( scode[cindex] == size ) break;
}
// find index of previous size
for ( pindex = 0; pindex < SCODE_MAX; pindex ++) {
if ( scode[pindex] == previousSize ) break;
}
if ( pindex < cindex ) {
/*
if way with = is better than - then use = next
else use - previous
0--<--pindex===>==cindex---<---SCODE_MAX
*/
if ( ((SCODE_MAX - cindex) + pindex ) > ( pindex - cindex ) ) {
// ( pindex - cindex ) times next
for ( ; pindex < cindex; pindex ++) {
fieldWriter.write( 3,2);
}
}
else {
// ((SCODE_MAX -cindex) + pindex ) fois previous
for ( pindex = SCODE_MAX - cindex + pindex; pindex > 0; pindex --) {
fieldWriter.write( 2,2);
}
}
}
else {
/*
if way with = is better than - then use = previous
else use - next
0-->--cindex===<==pindex--->---SCODE_MAX
*/
if ( ((SCODE_MAX - pindex) + cindex ) > cindex - pindex ) {
// ( cindex - pindex ) fois previous
for ( ; cindex < pindex; pindex --) {
fieldWriter.write( 2,2);
}
}
else {
// ((SCODE_MAX - pindex) + cindex ) fois next
for ( pindex = SCODE_MAX - pindex + cindex; pindex > 0; pindex --)
{
fieldWriter.write( 3,2);
}
}
}
}
// this is good size.
fieldWriter.write( 0,1);
writeAbs( point, size);
}
/* write given Point with size */
void writeAbs( Point point, int size) throws java.io.IOException {
int codeval;
int center, max;
previousSize = size;
if ( size > 32 ) {
fieldWriter.write( point.x, 32);
fieldWriter.write( point.y, 32);
}
else {
boolean nocenter = false;
/* size == 3 example :
X - >
Y 0 1 2
| 3 . 4-
v 5 6 7
specific application of general case bellow.
*/
/* X ->
Y 0
| 0 center max
v max
0 1 2 ...center.... (max - 1)
max 2 * max - 1
. (0,0) center * ( max + 1)
(max-1)*max -1 (max ^ 2) - 1
2 */
if ( size == 3 ) {
max = 3;
center = 1;
nocenter = true;
}
else {
max = ( 1 << ( size / 2 ) );
// biased center ( -center +1, center )
center = (max / 2) - 1;
}
/*
System.out.println( "size" + Integer.toString( size));
System.out.println( "max, center " + Integer.toString( max) + " " + Integer.toString( center));
System.out.println( "x, y " + Integer.toString( point.x) + " " + Integer.toString( point.y));
*/
codeval = point.x + center + (( point.y + center ) * max );
// central hole impossible BUT we should not really care ( in fact whole center square is impossible since covered by encoding with lower number of bits ) , avoid it only for size 3.
if (nocenter) {
if ( codeval == ( center * max ) + 1 ) {
System.out.println("!!! warning (0,0) point is invalid for compression !!!");
}
if ( codeval > (center * max) ){
codeval --;
}
}
// System.out.println( "code " + Integer.toString( codeval));
fieldWriter.write( codeval, size);
}
}
}

View File

@@ -0,0 +1,28 @@
/*
This file is part of ShareDrawWeb.
ShareDrawWeb 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.
ShareDrawWeb 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 ShareDrawWeb; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.artisanlogiciel.graphics;
import java.io.Serializable;
public class DrawException extends Exception implements Serializable {
public DrawException() {
super();
}
}

View File

@@ -0,0 +1,106 @@
/**
Drawing
contains a set of DrawingLine to create a Drawing
- feature of load / save
*/
package org.artisanlogiciel.graphics;
import java.awt.Graphics;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
import org.artisanlogiciel.graphics.Importer;
import org.artisanlogiciel.graphics.ResetException;
import org.artisanlogiciel.graphics.NoMoreLineException;
public class Drawing
{
private ArrayList<DrawingLine> lines;
public Drawing()
{
reset();
}
public void reset() {
lines = new ArrayList<DrawingLine>(10);
}
public void addLine( DrawingLine line) {
lines.add( line);
}
public void saveLines( DataOutputStream destination) throws
java.io.IOException {
destination.writeInt( lines.size());
for ( DrawingLine line : lines )
{
line.save( destination);
}
}
public void loadLines( DataInputStream source) throws
java.io.IOException {
int nb_lines = source.readInt();
DrawingLine line;
for ( int i = 0; i < nb_lines; i++ ) {
line = new DrawingLine();
line.load( source);
lines.add( line);
}
}
public void importImage( Importer importer) throws
java.io.IOException
{
importer.importInto(this);
}
public void saveLinesKompressed( DataOutputStream destination) throws
java.io.IOException {
destination.writeInt( lines.size());
for ( DrawingLine line : lines )
{
line.saveKompressed( destination);
}
}
public void loadLinesExpanded( DataInputStream source) throws
java.io.IOException {
// DrawLineExpander expander = new DrawLineExpander();
int nb_lines = source.readInt();
DrawingLine line;
for ( int i = 0; i < nb_lines; i++ ) {
line = new DrawingLine();
line.loadExpanded( source);
lines.add( line);
}
}
public int length() {
return lines.size();
}
public DrawingLine getLine( int line) throws ResetException, NoMoreLineException {
if ( line == lines.size() ) {
throw new NoMoreLineException();
}
if ( line > lines.size() ) {
throw new ResetException();
}
return lines.get( line);
}
public ArrayList<DrawingLine> getLines() {
return new ArrayList<DrawingLine>(lines);
}
/** Not a copy, use with care */
public ArrayList<DrawingLine> getInternLines() {
return lines;
}
}

View File

@@ -0,0 +1,96 @@
/**
DrawingLine
keep track of list of Points constituting a line
*/
package org.artisanlogiciel.graphics;
import java.awt.Point;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import org.artisanlogiciel.compression.graphics.DrawLineExpander;
import org.artisanlogiciel.compression.graphics.DrawLineKompressor;
public class DrawingLine implements Cloneable, Serializable
{
ArrayList<Point> lines;
public DrawingLine() {
lines = new ArrayList<>();
}
public void addPoint( Point point) {
lines.add( point);
}
public void setPoints( ArrayList<Point> points) {
lines = points;
}
public Object clone() throws java.lang.CloneNotSupportedException {
return super.clone();
}
private void writePoint( Point p, DataOutputStream destination) throws
java.io.IOException {
destination.writeInt( p.x);
destination.writeInt( p.y);
}
private void readPoint( DataInputStream source) throws java.io.IOException {
Point point = new Point( source.readInt(), source.readInt());
lines.add( point);
}
public void save( DataOutputStream destination) throws
java.io.IOException {
destination.writeInt( lines.size());
for (int i=0; i < lines.size(); i++) {
writePoint( (Point) lines.get(i), destination);
}
}
public void load( DataInputStream source) throws
java.io.IOException {
int point_number = source.readInt();
for (int i=0; i < point_number; i++) {
readPoint( source);
}
}
/**
* send over the stream a compressed version of this line
*/
public void saveKompressed( OutputStream destination) throws
java.io.IOException {
DrawLineKompressor kompressor = new DrawLineKompressor( lines);
kompressor.kompress( destination);
}
/**
* load form the stream a compressed version of this line
*/
public void loadExpanded( InputStream source) throws
java.io.IOException {
DrawLineExpander expander = new DrawLineExpander();
lines = expander.expand( source);
}
public ArrayList<Point> getPoints() {
return new ArrayList<Point>(lines);
}
public ArrayList<Point> internalGetPoints() {
return lines;
}
}

View File

@@ -0,0 +1,94 @@
package org.artisanlogiciel.graphics;
import java.awt.Point;
import java.io.DataInputStream;
/**
.IMA format is an old proprietary format for laser show program
it contain a list of point the laser beam should goe through,
x=255 has a special meaning to hide (255,254) ( send beam into the box) or show it (255,255): let is flow outside.
*/
public class IMAImporter implements Importer
{
final DataInputStream mStream;
boolean mBeanOn = false;
int mIndex =0;
boolean mDebug = false;
public IMAImporter(DataInputStream inputStream)
{
mStream=inputStream;
}
public void setDebug(boolean pDebug)
{
mDebug=pDebug;
}
@Override
public void importInto(Drawing drawing)
{
int x,y;
DrawingLine line = null;
mBeanOn = false;
try {
// little endian unsigned short
int pointCount = mStream.readUnsignedByte();
pointCount = ( 256 * mStream.readUnsignedByte() ) + pointCount;
if ( mDebug )
{
System.out.println("point count :" + pointCount);
}
for (int j = 0 ; j < pointCount; j+=2)
{
mIndex=j;
x = mStream.readUnsignedByte();
y = mStream.readUnsignedByte();
// special beam on/off
if ( ( x == 0xff ) && ( y >= 0xfe ) )
{
mBeanOn = ( y == 0xff);
if ( mDebug )
{
System.out.println("beam change at " + mIndex + " " + mBeanOn);
}
}
else
{
y = 255-y;
if ( mDebug )
{
System.out.println("point at " + mIndex + " " + mBeanOn + " x " + x + " y " + y);
}
if ( mBeanOn )
{
if (line == null )
{
line = new DrawingLine();
}
line.addPoint(new Point(x,y));
}
else
{
if ( line != null )
{
drawing.addLine(line);
line = null;
}
}
}
}
if ( line != null )
{
drawing.addLine(line);
line = null;
}
}
catch( Exception any)
{
System.err.println(" error at index " + mIndex);
any.printStackTrace(System.err);
}
}
}

View File

@@ -0,0 +1,143 @@
package org.artisanlogiciel.graphics;
import java.awt.Point;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
/**
* Write a DrawLine (using its internal Vector representation) into IMA format
* this is with loss ( ima is a 255x255 point resolution )
*
* @author philippe
*
*/
public class IMAWriter {
private final ArrayList<DrawingLine> mLines;
private int mByteCount = 0;
// need to compute bounding box and normalize to 255x255
private Point mOrig = new Point(100000,100000);
private Point mMax = new Point(-100000,-100000);
double ratioX = .1;
double ratioY = .1;
public IMAWriter(ArrayList<DrawingLine> pLines)
{
mLines = pLines;
setup();
}
private void updateOrigMax(Point p)
{
double ox = mOrig.getX(), oy = mOrig.getY(), mx = mMax.getX(), my = mMax.getY();
if (p.getX() < ox )
{
ox = p.getX();
}
if (p.getX() > mx)
{
mx = p.getX();
}
if (p.getY() < oy )
{
oy = p.getY();
}
if (p.getY() > my)
{
my = p.getY();
}
mOrig.setLocation(ox,oy);
mMax.setLocation(mx,my);
}
private void setup()
{
int count = 0;
for (DrawingLine line : mLines)
{
for (Point p : line.getPoints())
{
updateOrigMax(p);
count+=2;
}
// beam on + off
count+=4;
}
mByteCount=count;
if ( mMax.getX() != mOrig.getX())
{
ratioX = 255 / (mMax.getX() - mOrig.getX());
}
else
{
ratioX = 1.;
}
if ( mMax.getY() != mOrig.getY())
{
ratioY = 255 / (mMax.getY() - mOrig.getY());
}
else
{
ratioY = 1.;
}
}
public void writeTo(DataOutputStream pData)
throws IOException
{
int wrote = 0;
// writeheader : number of points ...
// little endian unsigned short.
pData.writeByte(mByteCount%256);
pData.writeByte(mByteCount/256);
for (DrawingLine line : mLines)
{
// write ima line
wrote += writeLine(pData, line.getPoints());
}
}
void writeBeamOnOff(DataOutputStream pData,boolean pOn)
throws IOException
{
pData.writeByte(0xff);
pData.writeByte(pOn ? 0xff : 0xfe);
}
void writePoint(DataOutputStream pData,Point pPoint)
throws IOException
{
int x = (int) ((pPoint.getX()-mOrig.getX()) * ratioX);
int y = 255 - ((int) ((pPoint.getY()-mOrig.getY()) * ratioY));
if ( x == 0xff )
{
x=0xfe;
}
pData.writeByte(x);
pData.writeByte(y);
}
int writeLine(DataOutputStream pData,ArrayList<Point> pPoints)
throws IOException
{
int count = 0;
for (Point p : pPoints)
{
writePoint(pData,p);
if ( count == 0 )
{
writeBeamOnOff(pData,true);
}
count++;
}
writeBeamOnOff(pData,false);
return 2*(count +2);
}
}

View File

@@ -0,0 +1,8 @@
package org.artisanlogiciel.graphics;
public interface Importer {
void importInto(Drawing drawing);
void setDebug(boolean pDebug);
}

View File

@@ -0,0 +1,31 @@
/*
This file is part of ShareDrawWeb.
ShareDrawWeb 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.
ShareDrawWeb 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 ShareDrawWeb; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.artisanlogiciel.graphics;
import java.io.Serializable;
public class NoMoreLineException
extends DrawException
implements Serializable
{
public NoMoreLineException() {
super();
}
}

View File

@@ -0,0 +1,28 @@
/*
This file is part of ShareDrawWeb.
ShareDrawWeb 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.
ShareDrawWeb 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 ShareDrawWeb; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.artisanlogiciel.graphics;
public class ResetException
extends DrawException
{
public ResetException() {
super();
}
}

View File

@@ -0,0 +1,65 @@
package org.artisanlogiciel.graphics;
import java.awt.Point;
//import java.io.DataOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.ArrayList;
/**
* Write a DrawLine (using its internal Vector representation) into svg
*
* @author philippe
*
*/
public class SvgWriter {
private final ArrayList<DrawingLine> mLines;
public SvgWriter(ArrayList<DrawingLine> pLines)
{
mLines = pLines;
}
public void writeTo(OutputStream pData)
throws IOException
{
pData.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>".getBytes("UTF8"));
pData.write("<svg>".getBytes("UTF8"));
for (DrawingLine line : mLines)
{
pData.write("<g><path ".getBytes("UTF8"));
pData.write("style=\"fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1\" d=\"".getBytes("UTF8"));
pData.write( getSvgPathString(line.getPoints()).getBytes("UTF8"));
pData.write(" \" /></g>".getBytes("UTF8"));
}
pData.write("</svg>".getBytes("UTF8"));
}
String getSvgPathString(ArrayList<Point> pPoints)
{
StringBuilder sb = new StringBuilder(pPoints.size() * 10);
Point second = null;
Point previous = null;
for ( Point p : pPoints)
{
if ( previous != null )
{
if ( second == null )
{
second = p;
// 'l' a line ( 'c' woudl be a curve )
sb.append(" l ");
}
sb.append( "" + (p.getX() - previous.getX()) + "," + (p.getY() - previous.getY()) );
previous = p;
}
else
{
sb.append("m " + p.getX() + "," + p.getY());
previous = p;
}
}
return sb.toString();
}
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff