Add Graphics plugin

This commit is contained in:
peterdell 2018-12-30 16:29:54 +01:00
parent a77f5cf51c
commit f28730cdc1
151 changed files with 17670 additions and 0 deletions

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry exported="true" kind="lib" path="lib/js.jar" sourcepath="lib/js-src.zip"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.wudsn.ide.gfx</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -0,0 +1,20 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: WUDSN IDE Graphics Plug-in
Bundle-SymbolicName: com.wudsn.ide.gfx;singleton:=true
Bundle-Version: 1.7.0.qualifier
Bundle-Activator: com.wudsn.ide.gfx.GraphicsPlugin
Bundle-Vendor: Peter Dell
Require-Bundle: com.wudsn.ide.base,
org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.ui,
org.eclipse.ui.editors,
org.eclipse.ui.ide,
org.eclipse.ui.console
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Bundle-Localization: plugin
Export-Package: com.wudsn.ide.gfx.editor
Bundle-ClassPath: lib/js.jar,
.

View File

@ -0,0 +1 @@
The method getAtariRGBColor(int) is undefined for the type PaletteTypeUtility com.wudsn.ide.base.common.HexUtility.getLongValueHexString( com.wudsn.ide.gfx.model.PaletteTypeUtility.getAtariRGBColor(0xff));

2
com.wudsn.ide.gfx/bin/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/com
/palettes

View File

@ -0,0 +1,15 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
plugin.properties,\
src/,\
schema/,\
icons/,\
build.properties,\
.project,\
.classpath,\
lib/js.jar,\
plugin_de_DE.properties

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,60 @@
#Properties file for com.wudsn.ide.gfx
com.wudsn.ide.gfx.converter.GraphicsFile.name=Graphics File
com.wudsn.ide.gfx.converter.apple2.AppleIIGraphicsFile.name=Apple II Graphics File
com.wudsn.ide.gfx.converter.atari8.Atari8GraphicsFile.name=Atari 8-bit Graphics File
com.wudsn.ide.gfx.converter.c64.C64GraphicsFile.name=C64 Graphics File
com.wudsn.ide.gfx.editor.GraphicsEditor.name=Graphics Editor
com.wudsn.ide.gfx.editor.GraphicsEditorOpenCommand.name=Open With Graphics Editor
com.wudsn.ide.gfx.editor.GraphicsCategory.name=Graphics
com.wudsn.ide.gfx.editor.ImageView.name=Image
com.wudsn.ide.gfx.editor.ImageViewShrinkToFit.name=Shrink
com.wudsn.ide.gfx.editor.ImageViewZoomToFit.name=Zoom
com.wudsn.ide.gfx.editor.ImagePaletteView.name=Image Palette
com.wudsn.ide.gfx.model.ConverterMode.RAW=Raw
com.wudsn.ide.gfx.model.ConverterMode.CNV=Conversion
com.wudsn.ide.gfx.model.ConverterDirection.FILES_TO_IMAGE=Files to Image
com.wudsn.ide.gfx.model.ConverterDirection.IMAGE_TO_FILES=Image to Files
com.wudsn.ide.gfx.model.Palette.TRUE_COLOR=True Color
com.wudsn.ide.gfx.model.Palette.HIRES_1=Hires (1)
com.wudsn.ide.gfx.model.Palette.HIRES_2=Hires (2)
com.wudsn.ide.gfx.model.Palette.HIRES_MANUAL=Hires (manual)
com.wudsn.ide.gfx.model.Palette.MULTI_1=Multi (1)
com.wudsn.ide.gfx.model.Palette.MULTI_2=Multi (2)
com.wudsn.ide.gfx.model.Palette.MULTI_3=Multi (3)
com.wudsn.ide.gfx.model.Palette.MULTI_4=Multi (4)
com.wudsn.ide.gfx.model.Palette.MULTI_5=Multi (5)
com.wudsn.ide.gfx.model.Palette.MULTI_6=Multi (6)
com.wudsn.ide.gfx.model.Palette.MULTI_MANUAL=Multi (manual)
com.wudsn.ide.gfx.model.Palette.GTIA_GREY_1=GITA grey (1)
com.wudsn.ide.gfx.model.Palette.GTIA_GREY_2=GITA grey (2)
com.wudsn.ide.gfx.model.Palette.GTIA_GREY_MANUAL=GTIA grey (manual)
com.wudsn.ide.gfx.model.PaletteType.FIXED=Fixed
com.wudsn.ide.gfx.model.PaletteType.TRUE_COLOR=True Color
com.wudsn.ide.gfx.model.PaletteType.ATARI_DEFAULT=ATARI (default)
com.wudsn.ide.gfx.model.PaletteType.ATARI_REAL=ATARI (real)
com.wudsn.ide.gfx.model.PaletteType.ATARI_XFORMER=ATARI (XFormer)
com.wudsn.ide.gfx.model.PaletteType.C64_NORMAL=C64 (normal)
com.wudsn.ide.gfx.model.PaletteType.C64_PAL=C64 (PAL)
com.wudsn.ide.gfx.converter.XYFactorDefaults.FACTOR_1_1=1 x 1
com.wudsn.ide.gfx.converter.XYFactorDefaults.FACTOR_2_1=2 x 1
com.wudsn.ide.gfx.converter.XYFactorDefaults.FACTOR_2_2=2 x 2
com.wudsn.ide.gfx.converter.XYFactorDefaults.FACTOR_4_2=4 x 2
com.wudsn.ide.gfx.converter.XYFactorDefaults.FACTOR_4_4=4 x 4
com.wudsn.ide.gfx.model.PixelType.HIRES=Hires
com.wudsn.ide.gfx.model.PixelType.MULTI=Multicolor
com.wudsn.ide.gfx.model.PixelType.GTIA_GREY=GTIA (grey)
com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE=Char Set File
com.wudsn.ide.gfx.converter.generic.CharMapConverter.CHAR_SET_FILE=Char Set File
com.wudsn.ide.gfx.converter.generic.CharMapConverter.CHAR_MAP_FILE=Char Map File
com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE=Bit Map File
com.wudsn.ide.gfx.converter.generic.TiledBitMapConverter.VIDEO_RAM_FILE=Video RAM File
com.wudsn.ide.gfx.converter.generic.TiledBitMapConverter.COLOR_RAM_FILE=Color RAM File
com.wudsn.ide.gfx.converter.c64.SpriteHiresConverter.SPRITE_FILE=Sprite File

View File

@ -0,0 +1,567 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension-point id="converters" name="Converters" schema="schema/com.wudsn.ide.gfx.converters.exsd"/>
<extension
point="org.eclipse.ui.commands">
<command
id="com.wudsn.ide.gfx.editor.GraphicsEditorOpenCommand"
name="%com.wudsn.ide.gfx.editor.GraphicsEditorOpenCommand.name">
</command>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="com.wudsn.ide.gfx.editor.GraphicsEditorOpenCommandHandler"
commandId="com.wudsn.ide.gfx.editor.GraphicsEditorOpenCommand">
</handler>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
locationURI="popup:org.eclipse.ui.popup.any?after=com.wudsn.ide.base.editor.hex.HexEditorOpenCommand">
<command
commandId="com.wudsn.ide.gfx.editor.GraphicsEditorOpenCommand"
id="com.wudsn.ide.gfx.editor.GraphicsEditorOpenCommand"
style="push">
<visibleWhen
checkEnabled="false">
<or>
<with
variable="activeMenuSelection">
<iterate
ifEmpty="false"
operator="or">
<instanceof
value="org.eclipse.core.resources.IFile">
</instanceof>
</iterate>
</with>
<with
variable="activeMenuEditorInput">
<iterate
ifEmpty="false"
operator="or">
<instanceof
value="org.eclipse.ui.IFileEditorInput">
</instanceof>
</iterate>
</with>
</or>
</visibleWhen>
</command>
</menuContribution>
</extension>
<extension
point="org.eclipse.core.contenttype.contentTypes">
<content-type
file-extensions="bmp, ico, gif, jpg, png, cnv"
id="com.wudsn.ide.gfx.converter.GraphicsFile"
name="%com.wudsn.ide.gfx.converter.GraphicsFile.name"
priority="normal">
</content-type>
<content-type
base-type="com.wudsn.ide.gfx.converter.GraphicsFile"
file-extensions="ap3, apc, chr, cci, cin, cpr, fnt, ghg, gr8, gr9, hip, hr, hr2, mcp, ilc, inp, int, mic, pic, plm, rip, sxs, tip"
id="com.wudsn.ide.gfx.converter.atari8.Atari8GraphicsFile"
name="%com.wudsn.ide.gfx.converter.atari8.Atari8GraphicsFile.name"
priority="normal">
</content-type>
<content-type
base-type="com.wudsn.ide.gfx.converter.GraphicsFile"
file-extensions="64c, chr, fnt, spr"
id="com.wudsn.ide.gfx.converter.c64.C64GraphicsFile"
name="%com.wudsn.ide.gfx.converter.c64.C64GraphicsFile.name"
priority="normal">
</content-type>
<content-type
base-type="com.wudsn.ide.gfx.converter.GraphicsFile"
file-extensions="hgr"
id="com.wudsn.ide.gfx.converter.apple2.AppleIIGraphicsFile"
name="%com.wudsn.ide.gfx.converter.apple2.AppleIIGraphicsFile.name"
priority="normal">
</content-type>
</extension>
<extension
point="org.eclipse.ui.editors">
<editor
class="com.wudsn.ide.gfx.editor.GraphicsEditor"
contributorClass="org.eclipse.ui.part.EditorActionBarContributor"
default="true"
extensions="bmp, ico, gif, jpg, png, cnv"
icon="icons/graphics-editor-16x16.gif"
id="com.wudsn.ide.gfx.editor.GraphicsEditor"
name="%com.wudsn.ide.gfx.editor.GraphicsEditor.name">
<contentTypeBinding
contentTypeId="com.wudsn.ide.gfx.converter.GraphicsFile">
</contentTypeBinding>
</editor>
</extension>
<extension
point="org.eclipse.ui.views">
<category
id="com.wudsn.ide.gfx.editor.GraphicsCategory"
name="%com.wudsn.ide.gfx.editor.GraphicsCategory.name">
</category>
<view
allowMultiple="false"
category="com.wudsn.ide.gfx.editor.GraphicsCategory"
class="com.wudsn.ide.gfx.editor.ImageView"
icon="icons/graphics-editor-16x16.gif"
id="com.wudsn.ide.gfx.editor.ImageView"
name="%com.wudsn.ide.gfx.editor.ImageView.name"
restorable="true">
</view>
<view
allowMultiple="false"
category="com.wudsn.ide.gfx.editor.GraphicsCategory"
class="com.wudsn.ide.gfx.editor.ImagePaletteView"
icon="icons/graphics-editor-16x16.gif"
id="com.wudsn.ide.gfx.editor.ImagePaletteView"
name="%com.wudsn.ide.gfx.editor.ImagePaletteView.name"
restorable="true">
</view>
</extension>
<extension
point="com.wudsn.ide.gfx.converters">
<converterGroup
name="Generic">
<converter
id="com.wudsn.ide.gfx.converter.generic.CharSet1x1HiresConverter"
name="Char Set 1x1 - Hires"
sourceFileExtensions="64c, chr, fnt"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="2">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</sourceFile>
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</targetFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.generic.CharSet1x1MultiColorConverter"
name="Char Set 1x1 - Multi Color"
targetImagePaletteSize="4"
targetImageDisplayAspect="2x1">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</sourceFile>
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</targetFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.generic.CharSet2x1HiresConverter"
name="Char Set 2x1 - Hires"
sourceFileExtensions="64c, chr, fnt"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="2">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</sourceFile>
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</targetFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.generic.CharSet2x2HiresConverter"
name="Char Set 2x2 - Hires"
sourceFileExtensions="sxs"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="2">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.generic.CharSet2x2MultiColorConverter"
name="Char Set 2x2 - MultiColor"
targetImagePaletteSize="4"
targetImageDisplayAspect="2x1">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.generic.CharMapHiresConverter"
name="Char Map - Hires"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="2">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</sourceFile>
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharMapConverter.CHAR_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.generic.CharMapMultiColorConverter"
name="Char Map - Multi Color"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="4">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</sourceFile>
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharMapConverter.CHAR_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.generic.TiledBitMapHiresConverter"
name="Tiled Bitmap - Hires"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="2">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.TiledBitMapConverter.VIDEO_RAM_FILE">
</sourceFile>
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.TiledBitMapConverter.COLOR_RAM_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.generic.TiledBitMapMultiColorConverter"
name="Tiled Bitmap - Multi Color"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="4">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.TiledBitMapConverter.VIDEO_RAM_FILE">
</sourceFile>
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.TiledBitMapConverter.COLOR_RAM_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.generic.TiledBitMap2x2MultiColorConverter"
name="Tiled Bitmap 2x2 - Multi Color"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="16">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.TiledBitMapConverter.VIDEO_RAM_FILE">
</sourceFile>
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.TiledBitMapConverter.COLOR_RAM_FILE">
</sourceFile>
</converter>
</converterGroup>
<converterGroup
name="Apple II">
<converter
id="com.wudsn.ide.gfx.converter.apple2.HiresGraphicsConverter"
name="Apple II - HGR"
sourceFileExtensions="hgr"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="6">
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</targetFile>
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
</converterGroup>
<converterGroup
name="Atari 2600">
<converter
id="com.wudsn.ide.gfx.converter.atari2600.AsymetricalPlayfieldConverter"
name="Atari 2600 - Asymetrical Playfield"
sourceFileExtensions="bin"
targetImageDisplayAspect="4x1"
targetImagePaletteSize="2">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</targetFile>
</converter>
</converterGroup>
<converterGroup
name="Atari 8-bit">
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapAP3Converter"
name="Atari 8-bit - AP3"
sourceFileExtensions="ap3"
targetImageDisplayAspect="4x1"
targetImagePaletteSize="0">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapAPACConverter"
name="Atari 8-bit - APAC"
sourceFileExtensions="apc"
targetImageDisplayAspect="4x2"
targetImagePaletteSize="0">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</targetFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapAPCConverter"
name="Atari 8-bit - APC"
sourceFileExtensions="apc, plm"
targetImageDisplayAspect="4x2"
targetImagePaletteSize="0">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapCINConverter"
name="Atari 8-bit - CCI/CIN"
sourceFileExtensions="cci, cin"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="0">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapCPRConverter"
name="Atari 8-bit - CPR"
sourceFileExtensions="cpr"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="4">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapGHGConverter"
name="Atari 8-bit - GHG"
sourceFileExtensions="ghg"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="2">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapGraphics8Converter"
name="Atari 8-bit - Graphics 8"
sourceFileExtensions="gr8"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="2">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</targetFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapGraphics9Converter"
name="Atari 8-bit - Graphics 9"
sourceFileExtensions="gr9"
targetImageDisplayAspect="4x1"
targetImagePaletteSize="16">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</targetFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapGraphics10Converter"
name="Atari 8-bit - Graphics 10"
targetImageDisplayAspect="4x1"
targetImagePaletteSize="16">
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</targetFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.CharMapGraphics12Converter"
name="Atari 8-bit - Graphics 12"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="5">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE">
</sourceFile>
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.CharMapConverter.CHAR_MAP_FILE">
</sourceFile>
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.CharMapConverter.CHAR_SET_FILE">
</targetFile>
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.CharMapConverter.CHAR_MAP_FILE">
</targetFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapGraphics15Converter"
name="Atari 8-bit - Graphics 15"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="4">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
<targetFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</targetFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapHIPConverter"
name="Atari 8-bit - HIP"
sourceFileExtensions="hip"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="0">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapHRConverter"
name="Atari 8-bit - HR"
sourceFileExtensions="hr"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="4">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapHR2Converter"
name="Atari 8-bit - HR2"
sourceFileExtensions="hr2"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="4">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapILCConverter"
name="Atari 8-bit - ILC"
sourceFileExtensions="ilc"
targetImageDisplayAspect="4x1"
targetImagePaletteSize="0">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapINPConverter"
name="Atari 8-bit - INP"
sourceFileExtensions="inp"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="8">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapRIPConverter"
name="Atari 8-bit - RIP"
sourceFileExtensions="rip"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="0">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapTIPConverter"
name="Atari 8-bit - TIP"
sourceFileExtensions="tip"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="0">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapINTConverter"
name="Atari 8-bit - INT"
sourceFileExtensions="int"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="8">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapKoalaConverter"
name="Atari 8-bit - Koala"
sourceFileExtensions="pic"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="4">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapMCPConverter"
name="Atari 8-bit - MCP"
sourceFileExtensions="mcp"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="8">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapMicroPainterConverter"
name="Atari 8-bit - Micropainter"
sourceFileExtensions="mic"
targetImageDisplayAspect="2x1"
targetImagePaletteSize="4">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
</converterGroup>
<converterGroup
name="C64">
<converter
id="com.wudsn.ide.gfx.converter.c64.SpriteHiresConverter"
name="C64 - Sprites - Hires"
sourceFileExtensions="spr"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="2">
<sourceFile
label="%com.wudsn.ide.gfx.converter.c64.SpriteHiresConverter.SPRITE_FILE">
</sourceFile>
</converter>
<converter
id="com.wudsn.ide.gfx.converter.c64.SpriteMultiColorConverter"
name="C64 - Sprites - Multi Color"
targetImagePaletteSize="4"
targetImageDisplayAspect="2x1">
<sourceFile
label="%com.wudsn.ide.gfx.converter.c64.SpriteHiresConverter.SPRITE_FILE">
</sourceFile>
</converter>
</converterGroup>
<converterGroup
name="Atari ST">
<converter
id="com.wudsn.ide.gfx.converter.atarist.InterleavedBitMap4Planes"
name="Atari ST - Interleaved Bitmap (4 Planes)"
sourceFileExtensions="sts"
targetImageDisplayAspect="1x1"
targetImagePaletteSize="16">
<sourceFile
label="%com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE">
</sourceFile>
</converter>
</converterGroup>
</extension>
</plugin>

View File

@ -0,0 +1,60 @@
#Properties file for com.wudsn.ide.gfx
com.wudsn.ide.gfx.converter.GraphicsFile.name=Grafik-Datei
com.wudsn.ide.gfx.converter.apple2.AppleIIGraphicsFile.name=Apple II Grafik-Datei
com.wudsn.ide.gfx.converter.atari8.Atari8GraphicsFile.name=Atari 8-bit Grafik-Datei
com.wudsn.ide.gfx.converter.c64.C64GraphicsFile.name=C64 Grafik-Datei
com.wudsn.ide.gfx.editor.GraphicsEditor.name=Grafik Editor
com.wudsn.ide.gfx.editor.GraphicsEditorOpenCommand.name=Öffnen mit Grafik Editor
com.wudsn.ide.gfx.editor.GraphicsCategory.name=Grafik
com.wudsn.ide.gfx.editor.ImageView.name=Bild
com.wudsn.ide.gfx.editor.ImageViewShrinkToFit.name=Verkleinern
com.wudsn.ide.gfx.editor.ImageViewZoomToFit.name=Vergrößern
com.wudsn.ide.gfx.editor.ImagePaletteView.name=Bildpalette
com.wudsn.ide.gfx.model.ConverterMode.RAW=Rohdaten
com.wudsn.ide.gfx.model.ConverterMode.CNV=Konverterieung
com.wudsn.ide.gfx.model.ConverterDirection.FILES_TO_IMAGE=Dateien zu Bild
com.wudsn.ide.gfx.model.ConverterDirection.IMAGE_TO_FILES=Bild zu Dateien
com.wudsn.ide.gfx.model.Palette.TRUE_COLOR=True Color
com.wudsn.ide.gfx.model.Palette.HIRES_1=Hires (1)
com.wudsn.ide.gfx.model.Palette.HIRES_2=Hires (2)
com.wudsn.ide.gfx.model.Palette.HIRES_MANUAL=Hires (manuell)
com.wudsn.ide.gfx.model.Palette.MULTI_1=Multi (1)
com.wudsn.ide.gfx.model.Palette.MULTI_2=Multi (2)
com.wudsn.ide.gfx.model.Palette.MULTI_3=Multi (3)
com.wudsn.ide.gfx.model.Palette.MULTI_4=Multi (4)
com.wudsn.ide.gfx.model.Palette.MULTI_5=Multi (5)
com.wudsn.ide.gfx.model.Palette.MULTI_6=Multi (6)
com.wudsn.ide.gfx.model.Palette.MULTI_MANUAL=Multi (manuell)
com.wudsn.ide.gfx.model.Palette.GTIA_GREY_1=GITA grau (1)
com.wudsn.ide.gfx.model.Palette.GTIA_GREY_2=GITA grau (2)
com.wudsn.ide.gfx.model.Palette.GTIA_GREY_MANUAL=GTIA grau (manuell)
com.wudsn.ide.gfx.model.PaletteType.FIXED=Fest
com.wudsn.ide.gfx.model.PaletteType.TRUE_COLOR=True Color
com.wudsn.ide.gfx.model.PaletteType.ATARI_DEFAULT=ATARI (standard)
com.wudsn.ide.gfx.model.PaletteType.ATARI_REAL=ATARI (real)
com.wudsn.ide.gfx.model.PaletteType.ATARI_XFORMER=ATARI (XFormer)
com.wudsn.ide.gfx.model.PaletteType.C64_NORMAL=C64 (normal)
com.wudsn.ide.gfx.model.PaletteType.C64_PAL=C64 (PAL)
com.wudsn.ide.gfx.converter.XYFactorDefaults.FACTOR_1_1=1 x 1
com.wudsn.ide.gfx.converter.XYFactorDefaults.FACTOR_2_1=2 x 1
com.wudsn.ide.gfx.converter.XYFactorDefaults.FACTOR_2_2=2 x 2
com.wudsn.ide.gfx.converter.XYFactorDefaults.FACTOR_4_2=4 x 2
com.wudsn.ide.gfx.converter.XYFactorDefaults.FACTOR_4_4=4 x 4
com.wudsn.ide.gfx.model.PixelType.HIRES=Hires
com.wudsn.ide.gfx.model.PixelType.MULTI=Multicolor
com.wudsn.ide.gfx.model.PixelType.GTIA_GREY=GTIA (grau)
com.wudsn.ide.gfx.converter.generic.CharSetConverter.CHAR_SET_FILE=Zeichensatz-Datei
com.wudsn.ide.gfx.converter.generic.CharMapConverter.CHAR_SET_FILE=Zeichensatz-Datei
com.wudsn.ide.gfx.converter.generic.CharMapConverter.CHAR_MAP_FILE=Char Map-Datei
com.wudsn.ide.gfx.converter.generic.BitMapConverter.BIT_MAP_FILE=Bit Map-Datei
com.wudsn.ide.gfx.converter.generic.TiledBitMapConverter.VIDEO_RAM_FILE=Video RAM-Datei
com.wudsn.ide.gfx.converter.generic.TiledBitMapConverter.COLOR_RAM_FILE=Color RAM-Datei
com.wudsn.ide.gfx.converter.c64.SpriteHiresConverter.SPRITE_FILE=Sprite-Datei

View File

@ -0,0 +1,183 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="com.wudsn.ide.gfx" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="com.wudsn.ide.gfx" id="converters" name="Converters"/>
</appinfo>
<documentation>
[Enter description of this extension point.]
</documentation>
</annotation>
<element name="extension">
<annotation>
<appinfo>
<meta.element />
</appinfo>
</annotation>
<complexType>
<sequence>
<element ref="converterGroup" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="converterGroup">
<complexType>
<sequence minOccurs="0" maxOccurs="unbounded">
<element ref="converter"/>
</sequence>
<attribute name="name" type="string">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
</complexType>
</element>
<element name="converter">
<complexType>
<choice>
<sequence>
<element ref="sourceFile" minOccurs="1" maxOccurs="10"/>
</sequence>
<sequence>
<element ref="targetFile" minOccurs="1" maxOccurs="10"/>
</sequence>
</choice>
<attribute name="id" type="string" use="required">
<annotation>
<documentation>
The id of the converter. Must be requal to its class name.
</documentation>
<appinfo>
<meta.attribute kind="java" basedOn="com.wudsn.ide.gfx.converter.Converter:"/>
</appinfo>
</annotation>
</attribute>
<attribute name="name" type="string" use="required">
<annotation>
<documentation>
The displayed name of the converter.
</documentation>
</annotation>
</attribute>
<attribute name="sourceFileExtensions" type="string">
<annotation>
<documentation>
Possibly empty sequence of file extensions which are recognized by the converter. Entries must be lower case without leading dot. Multiple entries are separated with comma.
</documentation>
</annotation>
</attribute>
<attribute name="targetImagePaletteSize" type="string" use="required">
<annotation>
<documentation>
Size of the target image palette. Must be 0 for a direct palette or a power of 2 for an indexed palette.
</documentation>
</annotation>
</attribute>
<attribute name="targetImageDisplayAspect" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
</complexType>
</element>
<element name="sourceFile">
<complexType>
<attribute name="label" type="string" use="required">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="targetFile">
<complexType>
<attribute name="label" type="string" use="required">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<annotation>
<appinfo>
<meta.section type="since"/>
</appinfo>
<documentation>
[Enter the first release in which this extension point appears.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="examples"/>
</appinfo>
<documentation>
[Enter extension point usage example here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="apiinfo"/>
</appinfo>
<documentation>
[Enter API information here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="implementation"/>
</appinfo>
<documentation>
[Enter information about supplied implementation of this extension point.]
</documentation>
</annotation>
</schema>

View File

@ -0,0 +1,124 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx;
import org.osgi.framework.BundleContext;
import com.wudsn.ide.base.common.AbstractIDEPlugin;
import com.wudsn.ide.gfx.converter.ConverterConsole;
import com.wudsn.ide.gfx.converter.ConverterRegistry;
import com.wudsn.ide.gfx.converter.ConverterScript;
import com.wudsn.ide.gfx.converter.ImageConverterData;
/**
* The activator class controls the plug-in life cycle. This plugin uses classes
* from the Mozilla Rhino in the classes {@link ConverterScript} and
* {@link ImageConverterData}. See <a href=
* "https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino/Download_Rhino"
* >https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino/
* Download_Rhino"</a>.
*/
public final class GraphicsPlugin extends AbstractIDEPlugin {
/**
* The plugin id.
*/
public static final String ID = "com.wudsn.ide.gfx";
/**
* Creates a new instance. Must be public for dynamic instantiation.
*/
private static GraphicsPlugin plugin;
/**
* The converter registry.
*/
private ConverterRegistry converterRegistry;
/**
* The converter console.
*/
private ConverterConsole converterConsole;
/**
* The constructor
*/
public GraphicsPlugin() {
converterRegistry = new ConverterRegistry();
}
@Override
protected String getPluginId() {
return ID;
}
/**
* {@inheritDoc}
*/
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
converterRegistry.init();
converterConsole = new ConverterConsole();
}
/**
* {@inheritDoc}
*/
@Override
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Gets the shared plugin instance
*
* @return The plug-in, not <code>null</code>.
*/
public static GraphicsPlugin getInstance() {
if (plugin == null) {
throw new IllegalStateException("Plugin not initialized or already stopped");
}
return plugin;
}
/**
* Gets the converter registry for this plugin.
*
* @return The converter registry, not <code>null</code>.
*/
public ConverterRegistry getConverterRegistry() {
if (converterRegistry == null) {
throw new IllegalStateException("Field 'converterRegistry' must not be null.");
}
return converterRegistry;
}
/**
* Gets the converter console for this plugin.
*
* @return The converter console, not <code>null</code>.
*/
public ConverterConsole getConverterConsole() {
return converterConsole;
}
}

View File

@ -0,0 +1,110 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx;
import org.eclipse.osgi.util.NLS;
import com.wudsn.ide.gfx.editor.GraphicsEditor;
/**
* Class which holds the localized text constants.
*
* @author Peter Dell
*/
public final class Texts extends NLS {
public static String FILE_SECTION_FIELD_SIZE_LABEL;
public static String FILE_SECTION_FIELD_SIZE_NO_DATA;
public static String FILE_SECTION_FIELD_OFFSET_LABEL;
public static String FIND_DEFAULT_FILE_CONVERTER_BUTTON_TOOLTIP;
public static String CREATE_CONVERSION_BUTTON_TOOLTIP;
public static String FILES_CONVERTER_DATA_VIEW_TAB;
public static String IMAGE_CONVERTER_DATA_VIEW_TAB;
public static String CONVERTER_PARAMETERS_CONVERTER_ID_LABEL;
public static String REFRESH_BUTTON_TOOLTIP;
public static String SAVE_IMAGE_BUTTON_TOOLTIP;
public static String SAVE_FILES_BUTTON_TOOLTIP;
public static String CONVERTER_PARAMETERS_BIT_MAP_FILE_PATH_LABEL;
public static String CONVERTER_PARAMETERS_BIT_MAP_FILE_SECTION_LABEL;
public static String CONVERTER_PARAMETERS_CHAR_SET_FILE_PATH_LABEL;
public static String CONVERTER_PARAMETERS_CHAR_SET_FILE_SECTION_LABEL;
public static String CONVERTER_PARAMETERS_CHAR_MAP_FILE_PATH_LABEL;
public static String CONVERTER_PARAMETERS_CHAR_MAP_FILE_SECTION_LABEL;
public static String CONVERTER_PARAMETERS_COLOR_MAP_FILE_PATH_LABEL;
public static String CONVERTER_PARAMETERS_COLOR_MAP_FILE_SECTION_LABEL;
public static String CONVERTER_PARAMETERS_IMAGE_FILE_PATH_LABEL;
// Files to image texts
public static String CONVERTER_PARAMETERS_COLUMNS_LABEL;
public static String CONVERTER_PARAMETERS_ROWS_LABEL;
public static String CONVERTER_PARAMETERS_SPACING_COLOR_LABEL;
public static String CONVERTER_PARAMETERS_SPACING_WIDTH_LABEL;
// Image to Files texts
public static String CONVERTER_PARAMETERS_USE_DEFAULT_SCRIPT_LABEL;
public static String CONVERTER_PARAMETERS_SCRIPT_LABEL;
public static String CONVERTER_DATA_IMAGE_DATA_WIDTH_LABEL;
public static String CONVERTER_DATA_IMAGE_DATA_HEIGHT_LABEL;
public static String CONVERTER_PARAMETERS_IMAGE_ASPECT_LABEL;
public static String CREATE_CONVERSION_DIALOG_TITLE;
public static String CREATE_CONVERSION_DIALOG_MESSAGE;
public static String SAVE_AS_DIALOG_TITLE;
public static String SAVE_AS_DIALOG_MESSAGE;
public static String CONVERTER_CONSOLE_TITLE;
public static String IMAGE_VIEW_ASPECT_LABEL;
public static String IMAGE_PALETTE_VIEW_EDIT_COLOR_ACTION_LABEL;
public static String IMAGE_PALETTE_VIEW_EDIT_COLOR_ACTION_TOOLTIP;
public static String IMAGE_PALETTE_VIEW_UNUSED_COLORS_ACTION_LABEL;
public static String IMAGE_PALETTE_VIEW_UNUSED_COLORS_ACTION_TOOLTIP;
public static String IMAGE_PALETTE_VIEW_INFO_NO_IMAGE;
public static String IMAGE_PALETTE_VIEW_INFO_INDEXED_PALETTE_IMAGE;
public static String IMAGE_PALETTE_VIEW_INFO_DIRECT_PALETTE_IMAGE;
public static String IMAGE_PALETTE_VIEW_COLUMN_INDEX_TEXT;
public static String IMAGE_PALETTE_VIEW_COLUMN_COLOR_HEX_TEXT;
public static String IMAGE_PALETTE_VIEW_COLUMN_COLOR_BINARY_TEXT;
public static String IMAGE_PALETTE_VIEW_COLUMN_RGB_COLOR_TEXT;
public static String IMAGE_PALETTE_VIEW_COLUMN_COLOR_COUNT_TEXT;
public static String IMAGE_PALETTE_VIEW_COLUMN_COLOR_COUNT_PERCENT_TEXT;
/**
* Messages for {@link GraphicsEditor}.
*/
public static String MESSAGE_S100 = "Source files loaded and converted in {0} ms";
public static String MESSAGE_E400;
/**
* Initializes the constants.
*/
static {
NLS.initializeMessages(Texts.class.getName(), Texts.class);
}
}

View File

@ -0,0 +1,73 @@
FILE_SECTION_FIELD_SIZE_LABEL=Size
FILE_SECTION_FIELD_SIZE_NO_DATA=No data
FILE_SECTION_FIELD_OFFSET_LABEL=Offset
FIND_DEFAULT_FILE_CONVERTER_BUTTON_TOOLTIP=Find Converter
CREATE_CONVERSION_BUTTON_TOOLTIP=Create Conversion...
# Tabs.
FILES_CONVERTER_DATA_VIEW_TAB=Files to Image
IMAGE_CONVERTER_DATA_VIEW_TAB=Image to Files
# Tab content
CONVERTER_PARAMETERS_CONVERTER_ID_LABEL=Converter
REFRESH_BUTTON_TOOLTIP=Refresh
SAVE_IMAGE_BUTTON_TOOLTIP=Save Image
SAVE_FILES_BUTTON_TOOLTIP=Save Files
CONVERTER_PARAMETERS_BIT_MAP_FILE_PATH_LABEL=Bit Map
CONVERTER_PARAMETERS_BIT_MAP_FILE_SECTION_LABEL=Bit Map
CONVERTER_PARAMETERS_CHAR_SET_FILE_PATH_LABEL=Char Set
CONVERTER_PARAMETERS_CHAR_SET_FILE_SECTION_LABEL=Char Set
CONVERTER_PARAMETERS_CHAR_MAP_FILE_PATH_LABEL=Char Map
CONVERTER_PARAMETERS_CHAR_MAP_FILE_SECTION_LABEL=Char Map
CONVERTER_PARAMETERS_COLOR_MAP_FILE_PATH_LABEL=Color Map
CONVERTER_PARAMETERS_COLOR_MAP_FILE_SECTION_LABEL=Color Map
CONVERTER_PARAMETERS_IMAGE_FILE_PATH_LABEL=Image
CONVERTER_PARAMETERS_COLUMNS_LABEL=Columns
CONVERTER_PARAMETERS_ROWS_LABEL=Rows
CONVERTER_PARAMETERS_SPACING_COLOR_LABEL=Spacing Color
CONVERTER_PARAMETERS_SPACING_WIDTH_LABEL=Spacing Width
CONVERTER_PARAMETERS_USE_DEFAULT_SCRIPT_LABEL=Use Default Script
CONVERTER_PARAMETERS_SCRIPT_LABEL=Script
CONVERTER_DATA_IMAGE_DATA_WIDTH_LABEL=Width
CONVERTER_DATA_IMAGE_DATA_HEIGHT_LABEL=Height
CONVERTER_PARAMETERS_IMAGE_ASPECT_LABEL=Aspect
# Dialogs.
CREATE_CONVERSION_DIALOG_TITLE=Create Conversion
CREATE_CONVERSION_DIALOG_MESSAGE=Creates a conversion file with the current settings, closes the current editor and opens the file a a new editor
SAVE_AS_DIALOG_TITLE=Save As
SAVE_AS_DIALOG_MESSAGE=Save the current conversion file to another location
# Converter Console
CONVERTER_CONSOLE_TITLE=Converter Console
# Image View.
IMAGE_VIEW_ASPECT_LABEL=Aspect
# Image Palette View.
IMAGE_PALETTE_VIEW_EDIT_COLOR_ACTION_LABEL=Edit
IMAGE_PALETTE_VIEW_EDIT_COLOR_ACTION_TOOLTIP=Edit the color of the currently selected table entry or select presets
IMAGE_PALETTE_VIEW_UNUSED_COLORS_ACTION_LABEL=Unused
IMAGE_PALETTE_VIEW_UNUSED_COLORS_ACTION_TOOLTIP=Toggle the display of the used colors in the indexed palette
IMAGE_PALETTE_VIEW_INFO_NO_IMAGE=No image
IMAGE_PALETTE_VIEW_INFO_INDEXED_PALETTE_IMAGE={0} bit indexed palette. {1} out of {2} colors used.
IMAGE_PALETTE_VIEW_INFO_DIRECT_PALETTE_IMAGE={0} bit direct palette. {1} colors used.
IMAGE_PALETTE_VIEW_COLUMN_INDEX_TEXT=Index
IMAGE_PALETTE_VIEW_COLUMN_COLOR_HEX_TEXT=Hex
IMAGE_PALETTE_VIEW_COLUMN_COLOR_BINARY_TEXT=Binary
IMAGE_PALETTE_VIEW_COLUMN_RGB_COLOR_TEXT=Color
IMAGE_PALETTE_VIEW_COLUMN_COLOR_COUNT_TEXT=Count
IMAGE_PALETTE_VIEW_COLUMN_COLOR_COUNT_PERCENT_TEXT=Percent
# Messages
MESSAGE_E400=Unused
MESSAGE_S100=Source files loaded and converted in {0} ms

View File

@ -0,0 +1,72 @@
FILE_SECTION_FIELD_SIZE_LABEL=Größe
FILE_SECTION_FIELD_SIZE_NO_DATA=Keine Daten
FILE_SECTION_FIELD_OFFSET_LABEL=Offset
FIND_DEFAULT_FILE_CONVERTER_BUTTON_TOOLTIP=Finde Konverter
CREATE_CONVERSION_BUTTON_TOOLTIP=Konvertierung anlegen...
# Tabs.
FILES_CONVERTER_DATA_VIEW_TAB=Datei nach Bild
IMAGE_CONVERTER_DATA_VIEW_TAB=Bild nach Datei
# Tab content
CONVERTER_PARAMETERS_CONVERTER_ID_LABEL=Konverter
REFRESH_BUTTON_TOOLTIP=Aktualisieren
SAVE_IMAGE_BUTTON_TOOLTIP=Bild speichern
SAVE_FILES_BUTTON_TOOLTIP=Dateien speichern
CONVERTER_PARAMETERS_BIT_MAP_FILE_PATH_LABEL=Bit Map
CONVERTER_PARAMETERS_BIT_MAP_FILE_SECTION_LABEL=Bit Map
CONVERTER_PARAMETERS_CHAR_SET_FILE_PATH_LABEL=Zeichensatz
CONVERTER_PARAMETERS_CHAR_SET_FILE_SECTION_LABEL=Zeichensatz
CONVERTER_PARAMETERS_CHAR_MAP_FILE_PATH_LABEL=Char Map
CONVERTER_PARAMETERS_CHAR_MAP_FILE_SECTION_LABEL=Char Map
CONVERTER_PARAMETERS_COLOR_MAP_FILE_PATH_LABEL=Color Map
CONVERTER_PARAMETERS_COLOR_MAP_FILE_SECTION_LABEL=Color Map
CONVERTER_PARAMETERS_IMAGE_FILE_PATH_LABEL=Bild
CONVERTER_PARAMETERS_COLUMNS_LABEL=Spalten
CONVERTER_PARAMETERS_ROWS_LABEL=Zeilen
CONVERTER_PARAMETERS_SPACING_COLOR_LABEL=Freiraumfarbe
CONVERTER_PARAMETERS_SPACING_WIDTH_LABEL=Freiraumbreite
CONVERTER_PARAMETERS_USE_DEFAULT_SCRIPT_LABEL=Standard Skript verwenden
CONVERTER_PARAMETERS_SCRIPT_LABEL=Skript
CONVERTER_DATA_IMAGE_DATA_WIDTH_LABEL=Breite
CONVERTER_DATA_IMAGE_DATA_HEIGHT_LABEL=Höhe
CONVERTER_PARAMETERS_IMAGE_ASPECT_LABEL=Seitenverhältnis
# Dialogs.
CREATE_CONVERSION_DIALOG_TITLE=Konvertierung anlegen
CREATE_CONVERSION_DIALOG_MESSAGE=Legt eine Konvertierungs-Datei mit den aktuellen Einstellungen an, schließt den aktuellen Editor und öffnet die neue Datei in einem neuen Editor
SAVE_AS_DIALOG_TITLE=Speichern unter
SAVE_AS_DIALOG_MESSAGE=Speicher die aktuelle Konvertierungs-Datei an einen anderen Ort
# Converter Console
CONVERTER_CONSOLE_TITLE=Konverter Konsole
# Image View.
IMAGE_VIEW_ASPECT_LABEL=Seitenverhältnis
# Image Palette View.
IMAGE_PALETTE_VIEW_EDIT_COLOR_ACTION_LABEL=Bearbeiten
IMAGE_PALETTE_VIEW_EDIT_COLOR_ACTION_TOOLTIP=Bearbeitet die Farbe des aktuelle ausgewählten Tabelleneintrages oder wählt eine der Voreinstellungen aus
IMAGE_PALETTE_VIEW_UNUSED_COLORS_ACTION_LABEL=Nicht verwendet
IMAGE_PALETTE_VIEW_UNUSED_COLORS_ACTION_TOOLTIP=Schaltet die Anzeige der nicht verwendeten Farben in der Index-Palette um
IMAGE_PALETTE_VIEW_INFO_NO_IMAGE=Kein Bild
IMAGE_PALETTE_VIEW_INFO_INDEXED_PALETTE_IMAGE={0} Bit Index-Palette. {1} von {2} Farben verwendet.
IMAGE_PALETTE_VIEW_INFO_DIRECT_PALETTE_IMAGE={0} Bit Direkt-Palette. {1} Farben verwendent.
IMAGE_PALETTE_VIEW_COLUMN_INDEX_TEXT=Index
IMAGE_PALETTE_VIEW_COLUMN_COLOR_HEX_TEXT=Hex
IMAGE_PALETTE_VIEW_COLUMN_COLOR_BINARY_TEXT=Binär
IMAGE_PALETTE_VIEW_COLUMN_RGB_COLOR_TEXT=Farbe
IMAGE_PALETTE_VIEW_COLUMN_COLOR_COUNT_TEXT=Anzahl
IMAGE_PALETTE_VIEW_COLUMN_COLOR_COUNT_PERCENT_TEXT=Prozent
# Messages
MESSAGE_E400=Nicht verwendet

View File

@ -0,0 +1,182 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.model.Palette;
public abstract class Converter {
private ConverterDefinition definition;
/**
* Constants for 1 bit pixels. Constants are defined as int to ensure no
* sign extension takes place when anding with byte values.
*/
protected static final int[] mask_1bit = new int[] { 0x80, 0x40, 0x20,
0x10, 0x08, 0x04, 0x02, 0x01 };
protected static final int[] shift_1bit = new int[] { 7, 6, 5, 4, 3, 2, 1,
0 };
/**
* Constants for 2 bit pixels.Constants are defined as int to ensure no sign
* extension takes place when anding with byte values.
*/
protected static final int[] mask_2bit = new int[] { 0xc0, 0x30, 0x0c, 0x03 };
protected static final int[] shift_2bit = new int[] { 6, 4, 2, 0 };
/**
* Constants for 4 bit pixels.Constants are defined as int to ensure no sign
* extension takes place when anding with byte values.
*/
protected static final int[] mask_4bit = new int[] { 0xf0, 0x0f };
protected static final int[] shift_4bit = new int[] { 4, 0 };
/**
* Creation is protected.
*/
protected Converter() {
}
/**
* Sets the definition of the Converter. Called by {@link ConverterRegistry}
* only.
*
* @param definition
* The definition if the Converter, not <code>null</code>.
*/
final void setDefinition(ConverterDefinition definition) {
if (definition == null) {
throw new IllegalArgumentException(
"Parameter 'type' must not be null.");
}
this.definition = definition;
}
/**
* Gets the definition of the Converter.
*
* @return The definition of the Converter, not <code>null</code>.
*/
public final ConverterDefinition getDefinition() {
if (definition == null) {
throw new IllegalStateException(
"Field 'definition' must not be null.");
}
return definition;
}
/**
* Determines if the given byte array can be converted to an image by this
* converter.
*
* @param bytes
* The byte array, not empty and not <code>null</code>.
*
* @return <code>true</code> if the given byte array can be converted to an
* image by this converter, <code>false</code> otherwise.
*
* @since 1.6.0
*/
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return false;
}
/**
* Converts the byte array content to image size and palette. Implementation
* shall call
* {@link #setImageSizeAndPalette(FilesConverterData, int, int, Palette, RGB[])}
* to set the corresponding values.
*
* @param data
* The file converter data container to be filled, not
* <code>null</code>.
* @param bytes
* The byte array, not empty and not <code>null</code>.
*
* @since 1.6.0
*/
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
throw new UnsupportedOperationException();
}
/**
* Sets the current converter, applies its defaults and then sets the image
* size and palette.
*
* @param data
* The file converter data container to be filled, not
* <code>null</code>.
* @param columns
* The number of columns.
* @param rows
* The number of rows.
* @param palette
* The palette, not <code>null</code>.
* @param paletteColors
* The palette colors or not <code>null</code> if palette is
* {@link Palette#TRUE_COLOR}.
*/
protected final void setImageSizeAndPalette(FilesConverterData data,
int columns, int rows, Palette palette, RGB[] paletteColors) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (palette == null) {
throw new IllegalArgumentException(
"Parameter 'palette' must not be null.");
}
if (paletteColors == null) {
if (!palette.equals(Palette.TRUE_COLOR)) {
throw new IllegalArgumentException(
"Parameter 'paletteColors' must not be null if palette is not TRUE_COLOR.");
}
paletteColors = new RGB[0];
}
FilesConverterParameters parameters;
parameters = data.getParameters();
parameters.setConverterId(this.getClass().getName());
parameters.setDisplayAspect(getDefinition()
.getTargetImageDisplayAspect());
parameters.setColumns(columns);
parameters.setRows(rows);
parameters.setPalette(palette);
parameters.setPaletteRGBs(paletteColors);
}
public abstract void convertToImageDataSize(FilesConverterData data);
/**
* Converts the files to an image.
*
* @param data
* The data, not <code>null</code>.
* @return <code>true</code> if an image was created and can be saved (i.e.
* pixels set), <code>false</code> if not.
*/
public abstract boolean convertToImageData(FilesConverterData data);
}

View File

@ -0,0 +1,131 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.graphics.ImageData;
/**
* Base class for {@link FilesConverterData} and {@link ImageConverterData}.
*
* @author Peter Dell
*
*/
public abstract class ConverterCommonData {
protected final ConverterData converterData;
private int imageDataWidth;
private int imageDataHeight;
protected ImageData imageData;
private ImageColorHistogram imageColorHistogram;
ConverterCommonData(ConverterData converterData) {
if (converterData == null) {
throw new IllegalArgumentException(
"Parameter 'converterData' must not be null.");
}
this.converterData = converterData;
imageData = null;
imageColorHistogram = new ImageColorHistogram();
}
public final IPath getFilePathPrefix() {
IPath result;
if (converterData.isValid()) {
result = converterData.getFile().getFullPath()
.removeLastSegments(1);
} else {
result = new Path("");
}
return result;
}
public abstract boolean isCreateConversionEnabled();
public abstract boolean isValid();
public abstract boolean isRefreshEnabled();
protected void clear() {
imageData = null;
imageColorHistogram.clear();
}
public final void setImageDataWidth(int width) {
this.imageDataWidth = width;
}
public final int getImageDataWidth() {
return imageDataWidth;
}
public final void setImageDataHeight(int height) {
this.imageDataHeight = height;
}
public final int getImageDataHeight() {
return imageDataHeight;
}
/**
* Sets the image data.
*
* @param imageData
* The image data, may be <code>null</code>.
*/
final void setImageData(ImageData imageData) {
this.imageData = imageData;
imageColorHistogram = null;
}
/**
* Gets the image data.
*
* @return The image data or <code>null</code>.
*/
public final ImageData getImageData() {
return imageData;
}
/**
* Sets the image color histogram.
*
* @param imageColorHistogram
* The image color histogram, may be <code>null</code>.
*
* @since 1.6.0
*/
final void setImageColorHistogram(ImageColorHistogram imageColorHistogram) {
this.imageColorHistogram = imageColorHistogram;
}
/**
* Gets the image color histogram.
*
* @return The image color histogram, not <code>null</code>.
*/
public final ImageColorHistogram getImageColorHistogram() {
return imageColorHistogram;
}
}

View File

@ -0,0 +1,234 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import com.wudsn.ide.gfx.model.Aspect;
import com.wudsn.ide.gfx.model.GraphicsPropertiesSerializer;
public abstract class ConverterCommonParameters {
/**
* Names of the attributes.
*
* @author Peter Dell
*
*/
public static final class Attributes {
/**
* Creation is private.
*/
private Attributes() {
}
public static final String CONVERTER_ID = "converterId";
public static final String IMAGE_ASPECT = "imageAspect";
// Display attributes.
public static final String DISPLAY_ASPECT = "displayAspect";
public static final String DISPLAY_SHRINK_TO_FIT = "displayShrinkToFit";
public static final String DISPLAY_ZOOM_TO_FIT = "displayZoomToFit";
}
/**
* Defaults of the attributes.
*
* @author Peter Dell
*
*/
private static final class Defaults {
/**
* Creation is protected.
*/
private Defaults() {
}
public static final String CONVERTER_ID = "";
public static final Aspect IMAGE_ASPECT = new Aspect(1, 1);
public static final Aspect DISPLAY_ASPECT = new Aspect(1, 1);
public static final boolean DISPLAY_SHRINK_TO_FIT = false;
public static final boolean DISPLAY_ZOOM_TO_FIT = true;
}
/**
* Message ids of the attributes.
*
* @author Peter Dell
*
*/
public static final class MessageIds {
/**
* Creation is private.
*/
private MessageIds() {
}
public static final int CONVERTER_ID = 1000;
public static final int IMAGE_ASPECT = 1001;
public static final int DISPLAY_ASPECT = 1002;
}
protected String converterId;
private Aspect imageAspect;
private Aspect displayAspect;
private boolean displayShrinkToFit;
private boolean displayZoomToFit;
ConverterCommonParameters() {
}
protected void setDefaults() {
converterId = Defaults.CONVERTER_ID;
imageAspect = Defaults.IMAGE_ASPECT;
displayAspect = Defaults.DISPLAY_ASPECT;
displayShrinkToFit = Defaults.DISPLAY_SHRINK_TO_FIT;
displayZoomToFit = Defaults.DISPLAY_ZOOM_TO_FIT;
}
public abstract void setConverterId(String value);
public final String getConverterId() {
return converterId;
}
public final void setImageAspect(Aspect value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.imageAspect = value;
}
public final Aspect getImageAspect() {
return imageAspect;
}
public final void setDisplayAspect(Aspect value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.displayAspect = value;
}
public final Aspect getDisplayAspect() {
return displayAspect;
}
public final void setDisplayShrinkToFit(boolean displayShrinkToFit) {
this.displayShrinkToFit = displayShrinkToFit;
}
public final boolean isDisplayShrinkToFit() {
return displayShrinkToFit;
}
public final void setDisplayZoomToFit(boolean displayZoomToFit) {
this.displayZoomToFit = displayZoomToFit;
}
public final boolean isDisplayZoomToFit() {
return displayZoomToFit;
}
protected void copyTo(ConverterCommonParameters target) {
if (target == null) {
throw new IllegalArgumentException(
"Parameter 'target' must not be null.");
}
target.setConverterId(converterId);
target.setImageAspect(imageAspect);
target.setDisplayAspect(displayAspect);
target.setDisplayShrinkToFit(displayShrinkToFit);
target.setDisplayZoomToFit(displayZoomToFit);
}
protected boolean equals(ConverterCommonParameters target) {
if (target == null) {
throw new IllegalArgumentException(
"Parameter 'target' must not be null.");
}
boolean result;
result = target.getImageAspect().equals(imageAspect);
result = result && target.getDisplayAspect().equals(displayAspect);
result = result && target.isDisplayShrinkToFit() == displayShrinkToFit;
result = result && target.isDisplayZoomToFit() == displayZoomToFit;
return result;
}
protected void serialize(GraphicsPropertiesSerializer serializer, String key) {
if (serializer == null) {
throw new IllegalArgumentException(
"Parameter 'serializer' must not be null.");
}
if (key == null) {
throw new IllegalArgumentException(
"Parameter 'key' must not be null.");
}
GraphicsPropertiesSerializer ownSerializer;
ownSerializer = new GraphicsPropertiesSerializer();
ownSerializer.writeString(Attributes.CONVERTER_ID, converterId);
ownSerializer.writeAspect(Attributes.IMAGE_ASPECT, imageAspect);
ownSerializer.writeAspect(Attributes.DISPLAY_ASPECT, displayAspect);
ownSerializer.writeBoolean(Attributes.DISPLAY_SHRINK_TO_FIT,
displayShrinkToFit);
ownSerializer.writeBoolean(Attributes.DISPLAY_ZOOM_TO_FIT,
displayZoomToFit);
serializer.writeProperties(key, ownSerializer);
}
protected void deserialize(GraphicsPropertiesSerializer serializer,
String key) {
if (serializer == null) {
throw new IllegalArgumentException(
"Parameter 'serializer' must not be null.");
}
if (key == null) {
throw new IllegalArgumentException();
}
GraphicsPropertiesSerializer ownSerializer;
ownSerializer = new GraphicsPropertiesSerializer();
serializer.readProperties(key, ownSerializer);
setConverterId(ownSerializer.readString(Attributes.CONVERTER_ID,
Defaults.CONVERTER_ID));
imageAspect = ownSerializer.readXYFactor(Attributes.DISPLAY_ASPECT,
Defaults.IMAGE_ASPECT);
displayAspect = ownSerializer.readXYFactor(Attributes.DISPLAY_ASPECT,
Defaults.DISPLAY_ASPECT);
displayShrinkToFit = ownSerializer.readBoolean(
Attributes.DISPLAY_SHRINK_TO_FIT,
Defaults.DISPLAY_SHRINK_TO_FIT);
displayZoomToFit = ownSerializer.readBoolean(
Attributes.DISPLAY_ZOOM_TO_FIT, Defaults.DISPLAY_ZOOM_TO_FIT);
}
}

View File

@ -0,0 +1,101 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.io.PrintStream;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;
import com.wudsn.ide.gfx.Texts;
/**
* The console to show the user the output from the converter.
*
* @author Peter Dell
*/
public final class ConverterConsole {
private IConsoleManager consoleManager;
public MessageConsole console;
private MessageConsoleStream messageStream;
private PrintStream printStream;
/**
* Create a new console-window.
*
*/
public ConverterConsole() {
consoleManager = ConsolePlugin.getDefault().getConsoleManager();
console = new MessageConsole(Texts.CONVERTER_CONSOLE_TITLE, null);
consoleManager.addConsoles(new IConsole[] { console });
messageStream = console.newMessageStream();
messageStream.setActivateOnWrite(false);
messageStream.print("");
printStream = new PrintStream(messageStream);
}
/**
* Brings this console view instance to front in the console view editor
* part.
*
* @param consoleView
* The console view editor part, not <code>null</code>.
*/
public void display(IConsoleView consoleView) {
if (consoleView == null) {
throw new IllegalArgumentException(
"Parameter 'consoleView' must not be null.");
}
consoleView.display(console);
}
/**
* Add a line to console.
*
* @param message
* The message to print, not <code>null</code>.
*/
public void println(String message) {
if (message == null) {
throw new IllegalArgumentException(
"Parameter 'message' must not be null.");
}
messageStream.println(message);
}
/**
* Gets a print messageStream to write to this console.
*
* @return The print messageStream, not <code>null</code>.
*/
public PrintStream getPrintStream() {
return printStream;
}
}

View File

@ -0,0 +1,161 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import com.wudsn.ide.base.common.IPathUtility;
import com.wudsn.ide.gfx.model.ConverterDirection;
import com.wudsn.ide.gfx.model.ConverterMode;
public final class ConverterData {
private static final class Defaults {
/**
* Creation is private.
*/
private Defaults() {
}
public static final ConverterMode CONVERTER_MODE = ConverterMode.NONE;
}
private IFile file;
private IPath filePathPrefix;
private ConverterMode converterMode;
private ConverterParameters parameters;
private ConverterParameters parametersBackup;
private FilesConverterData filesConverterData;
private ImageConverterData imageConverterData;
ConverterData() {
parameters = new ConverterParameters();
parametersBackup = new ConverterParameters();
filesConverterData = new FilesConverterData(this);
imageConverterData = new ImageConverterData(this);
clear();
}
public void setFile(IFile file) {
this.file = file;
if (file != null) {
filePathPrefix = file.getFullPath().removeLastSegments(1);
} else {
filePathPrefix = IPathUtility.createEmptyPath();
}
}
public IFile getFile() {
return file;
}
public IPath getFilePathPrefix() {
return filePathPrefix;
}
public boolean isValid() {
return file != null;
}
public void setConverterMode(ConverterMode value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.converterMode = value;
}
public ConverterMode getConverterMode() {
return converterMode;
}
public boolean isValidFile() {
return isValid()
&& (converterMode == ConverterMode.RAW_FILE || converterMode == ConverterMode.CNV);
}
public boolean isValidImage() {
return isValid()
&& (converterMode == ConverterMode.RAW_IMAGE || converterMode == ConverterMode.CNV);
}
public boolean isValidConversion() {
return isValid() && converterMode == ConverterMode.CNV;
}
public ConverterDirection getConverterDirection() {
return parameters.getConverterDirection();
}
public ConverterParameters getParameters() {
return parameters;
}
public ConverterCommonData getConverterCommonData() {
switch (parameters.getConverterDirection()) {
case FILES_TO_IMAGE:
return filesConverterData;
case IMAGE_TO_FILES:
return imageConverterData;
default:
throw new IllegalStateException("Unknown converter direction "
+ parameters.getConverterDirection() + ".");
}
}
public FilesConverterData getFilesConverterData() {
return filesConverterData;
}
public ImageConverterData getImageConverterData() {
return imageConverterData;
}
public void clear() {
file = null;
clearContent();
}
public void clearContent() {
converterMode = Defaults.CONVERTER_MODE;
parameters.setDefaults();
filesConverterData.clear();
imageConverterData.clear();
}
final void copyParametersToBackup() {
parametersBackup.setDefaults();
parameters.copyTo(parametersBackup);
}
public boolean isChanged() {
boolean result;
result = !parameters.equals(parametersBackup);
return result;
}
}

View File

@ -0,0 +1,787 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.base.BasePlugin;
import com.wudsn.ide.base.common.FileUtility;
import com.wudsn.ide.base.common.HexUtility;
import com.wudsn.ide.base.common.IPathUtility;
import com.wudsn.ide.base.common.StringUtility;
import com.wudsn.ide.base.gui.MessageManager;
import com.wudsn.ide.gfx.GraphicsPlugin;
import com.wudsn.ide.gfx.converter.FilesConverterParameters.SourceFile;
import com.wudsn.ide.gfx.converter.ImageConverterParameters.TargetFile;
import com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapGraphics8Converter;
import com.wudsn.ide.gfx.model.ConverterDirection;
import com.wudsn.ide.gfx.model.ConverterMode;
public final class ConverterDataLogic {
private MessageManager messageManager;
private FilesConverterDataLogic filesConverterDataLogic;
/**
* Helper class to detect the support image file formats by their extension.
*
* @author Peter Dell
*/
private static final class ImageExtensions {
public static final String CNV = "cnv";
public static final String BMP = "bmp";
public static final String ICO = "ico";
public static final String GIF = "gif";
public static final String JPG = "jpg";
public static final String PNG = "png";
public static final int UNKNOWN_FORMAT = -1;
public static int getImageFormat(IPath filePath) {
int result;
String fileExtension = filePath.getFileExtension();
if (fileExtension == null) {
result = UNKNOWN_FORMAT;
} else if (fileExtension.equalsIgnoreCase(BMP)) {
result = SWT.IMAGE_BMP;
} else if (fileExtension.equalsIgnoreCase(ICO)) {
result = SWT.IMAGE_ICO;
} else if (fileExtension.equalsIgnoreCase(GIF)) {
result = SWT.IMAGE_GIF;
} else if (fileExtension.equalsIgnoreCase(JPG)) {
result = SWT.IMAGE_JPEG;
} else if (fileExtension.equalsIgnoreCase(PNG)) {
result = SWT.IMAGE_PNG;
} else {
result = UNKNOWN_FORMAT;
}
return result;
}
}
public ConverterDataLogic(MessageManager messageManager) {
if (messageManager == null) {
throw new IllegalArgumentException("Parameter 'messageManager' must not be null.");
}
this.messageManager = messageManager;
filesConverterDataLogic = new FilesConverterDataLogic();
}
public ConverterData createData() {
return new ConverterData();
}
public void load(ConverterData data) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
data.clearContent();
IFile file = data.getFile();
String fileName = file.getFullPath().lastSegment();
String extension = file.getFileExtension();
if (extension == null) {
extension = "";
} else {
extension = extension.toLowerCase();
}
if (extension.equals(ImageExtensions.CNV)) {
data.setConverterMode(ConverterMode.CNV);
try {
data.getParameters().read(file);
} catch (CoreException ex) {
messageManager.sendMessage(0, ex);
}
loadSources(data, true);
} else {
int imageFormat = ImageExtensions.getImageFormat(file.getFullPath());
if (imageFormat != ImageExtensions.UNKNOWN_FORMAT) {
data.setConverterMode(ConverterMode.RAW_IMAGE);
data.getParameters().setConverterDirection(ConverterDirection.IMAGE_TO_FILES);
data.getImageConverterData().getParameters().setImageFilePath(fileName);
data.getImageConverterData().getParameters()
.setConverterId(LinearBitMapGraphics8Converter.class.getName());
loadSources(data, true);
} else {
data.setConverterMode(ConverterMode.RAW_FILE);
data.getParameters().setConverterDirection(ConverterDirection.FILES_TO_IMAGE);
data.getFilesConverterData().getParameters().setDefaultSourceFilePath(fileName);
data.getFilesConverterData().getParameters().setImageFilePath(fileName + "." + ImageExtensions.PNG);
findDefaultFileConverter(data);
loadSources(data, true);
}
}
}
public void findDefaultFileConverter(ConverterData data) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
FilesConverterData filesConverterData;
filesConverterData = data.getFilesConverterData();
FilesConverterParameters fileConverterParameters = filesConverterData.getParameters();
IPath filePathPrefix = filesConverterData.getFilePathPrefix();
SourceFile sourceFile = fileConverterParameters.getSourceFile(0);
IPath filePath = Path.fromPortableString(sourceFile.getPath());
filePath = IPathUtility.makeAbsolute(filePath, filePathPrefix, false);
byte[] bytes = loadSourceFile(sourceFile.getPathMessageId(), filePath);
// TODO: If bytes is null or length is 0, an error message should be displayed instead.
if (bytes != null) {
String fileExtension = filePath.getFileExtension();
if (fileExtension != null) {
fileExtension = fileExtension.toLowerCase();
} else {
fileExtension = "";
}
filesConverterDataLogic.findDefaultFileConverter(filesConverterData, bytes, fileExtension);
}
}
public boolean loadSources(ConverterData data, boolean copyToBackup) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
boolean success;
success = true;
switch (data.getConverterDirection()) {
case FILES_TO_IMAGE:
FilesConverterData filesConverterData;
filesConverterData = data.getFilesConverterData();
FilesConverterParameters fileConverterParameters = filesConverterData.getParameters();
IPath filePathPrefix = filesConverterData.getFilePathPrefix();
for (int i = 0; i < fileConverterParameters.getSourceFilesSize(); i++) {
SourceFile sourceFile = fileConverterParameters.getSourceFile(i);
IPath filePath = Path.fromPortableString(sourceFile.getPath());
filePath = IPathUtility.makeAbsolute(filePath, filePathPrefix, false);
byte[] bytes = loadSourceFile(sourceFile.getPathMessageId(), filePath);
filesConverterData.setSourceFileBytes(sourceFile.getId(), bytes);
if (bytes == null) {
success = false;
}
}
break;
case IMAGE_TO_FILES:
ImageConverterData imageConverterData;
imageConverterData = data.getImageConverterData();
filePathPrefix = imageConverterData.getFilePathPrefix();
IPath filePath = Path.fromPortableString(imageConverterData.getParameters().getImageFilePath());
filePath = IPathUtility.makeAbsolute(filePath, filePathPrefix, false);
ImageData imageData = loadSourceImage(ImageConverterParameters.MessageIds.IMAGE_FILE_PATH, filePath);
imageConverterData.setImageData(imageData);
if (imageData != null) {
// Remember last loaded state.
success = true;
} else {
success = false;
}
break;
default:
throw new RuntimeException("Unknown converter direction '" + data.getConverterDirection() + "'.");
}
// Remember last loaded state.
if (success && copyToBackup) {
data.copyParametersToBackup();
}
return success;
}
/**
* Applies the converter based default values after the converter has been
* selected.
*
* @param data
* The converter data, not <code>null</code>.
*/
public void applyDefaults(ConverterData data) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
switch (data.getConverterDirection()) {
case FILES_TO_IMAGE:
filesConverterDataLogic.applyDefaults(data.getFilesConverterData());
break;
case IMAGE_TO_FILES:
break;
default:
throw new RuntimeException("Unknown converter direction '" + data.getConverterDirection() + "'.");
}
}
public ConverterData createConversion(ConverterData data) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
if (!data.isValid()) {
throw new IllegalStateException("Converter data is not valid.");
}
if (data.getConverterMode() != ConverterMode.RAW_FILE && data.getConverterMode() != ConverterMode.RAW_IMAGE) {
throw new IllegalStateException("Converter data is not in mode RAW_FILE or RAW_IMAGE.");
}
// Compute new file name.
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IPath saveAsPath = data.getFile().getFullPath().addFileExtension(ImageExtensions.CNV);
IFile saveAsFile = workspaceRoot.getFile(saveAsPath);
// Compute new content.
ConverterData newConverterData = new ConverterData();
newConverterData.setConverterMode(ConverterMode.CNV);
newConverterData.setFile(saveAsFile);
data.getParameters().copyTo(newConverterData.getParameters());
return newConverterData;
}
public IFile saveConversion(ConverterData data, IProgressMonitor monitor) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
IFile saveFile;
String saveFilePath;
saveFile = data.getFile();
saveFilePath = saveFile.getFullPath().toString();
try {
InputStream inputStream;
inputStream = data.getParameters().getContents(saveFilePath);
if (saveFile.exists()) {
saveFile.setContents(inputStream, false, false, monitor);
} else {
saveFile.create(inputStream, true, monitor);
}
// Remember last saved state.
data.copyParametersToBackup();
} catch (CoreException ex) {
messageManager.sendMessage(0, ex);
saveFile = null;
}
return saveFile;
}
public void saveTargets(ConverterData data) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
IPath filePathPrefix;
IPath filePath;
if (convert(data)) {
switch (data.getConverterDirection()) {
case FILES_TO_IMAGE:
FilesConverterData filesConverterData;
filesConverterData = data.getFilesConverterData();
filePathPrefix = filesConverterData.getFilePathPrefix();
filePath = Path.fromPortableString(filesConverterData.getParameters().getImageFilePath());
filePath = IPathUtility.makeAbsolute(filePath, filePathPrefix, false);
saveTargetImage(FilesConverterParameters.MessageIds.IMAGE_FILE_PATH, filePath,
filesConverterData.getImageData());
break;
case IMAGE_TO_FILES:
ImageConverterData imageConverterData;
ImageConverterParameters imageConverterParameters;
imageConverterData = data.getImageConverterData();
imageConverterParameters = imageConverterData.getParameters();
filePathPrefix = imageConverterData.getFilePathPrefix();
int size = imageConverterData.getConverter().getDefinition().getTargetFileDefinitions().size();
int minSize = Math.min(size, imageConverterParameters.getTargetFilesSize());
boolean saved = true;
for (int i = 0; i < minSize; i++) {
TargetFile targetFile = imageConverterParameters.getTargetFile(i);
filePath = Path.fromPortableString(targetFile.getPath());
filePath = IPathUtility.makeAbsolute(filePath, filePathPrefix, false);
saved &= saveTargetFile(targetFile.getPathMessageId(), filePath,
imageConverterData.getTargetFileBytes(targetFile.getId()));
}
if (!saved) {
for (int i = 0; i < minSize; i++) {
TargetFile targetFile = imageConverterParameters.getTargetFile(i);
messageManager.sendMessage(targetFile.getPathMessageId(), IStatus.ERROR,
"No target file with file path and content present");
}
}
break;
default:
throw new RuntimeException("Unknown converter direction '" + data.getConverterDirection() + "'.");
}
}
}
/**
* Saves a target file, if path and content are present. Empty content is
* allowed, <code>null</code> content is interpreted as missing file.
*
* @param messageId
* The message id.
* @param filePath
* The target file path, may be empty, not <code>null</code>.
* @param bytes
* The target file content, may be empty or <code>null</code>.
*
* @return <code>true</code> if the file was save, <code>false</code>
* otherwise.
*/
private boolean saveTargetFile(int messageId, IPath filePath, byte[] bytes) {
if (filePath == null) {
throw new IllegalArgumentException("Parameter 'filePath' must not be null.");
}
boolean result;
if (filePath.isEmpty()) {
messageManager.sendMessage(messageId, IStatus.WARNING, "No target file path specified");
return false;
}
if (bytes == null) {
messageManager.sendMessage(messageId, IStatus.INFO, "File {0} not saved as there is no data for this file",
filePath.toPortableString());
return false;
}
IWorkspaceRoot workspaceRoot;
IFile saveFile;
IProgressMonitor monitor;
result = false;
workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
saveFile = workspaceRoot.getFile(filePath);
monitor = null;
try {
InputStream inputStream;
inputStream = new ByteArrayInputStream(bytes);
if (saveFile.exists()) {
saveFile.setContents(inputStream, false, false, monitor);
} else {
saveFile.create(inputStream, true, monitor);
}
} catch (CoreException ex) {
messageManager.sendMessage(0, ex);
saveFile = null;
}
if (saveFile != null) {
messageManager.sendMessage(messageId, IStatus.INFO, "File {0} saved with ${1} bytes",
filePath.toPortableString(), HexUtility.getLongValueHexString(bytes.length));
result = true;
}
return result;
}
private void saveTargetImage(int messageId, IPath filePath, ImageData imageData) {
if (filePath == null) {
throw new IllegalArgumentException("Parameter 'filePath' must not be null.");
}
if (filePath.isEmpty()) {
messageManager.sendMessage(messageId, IStatus.ERROR, "No image path specified");
return;
}
if (imageData == null) {
messageManager.sendMessage(messageId, IStatus.ERROR,
"Image {0} not saved as there is no data for this image", filePath.toPortableString());
return;
}
ImageLoader imageLoader = new ImageLoader();
imageLoader.data = new ImageData[] { imageData };
int format = ImageExtensions.getImageFormat(filePath);
if (format == ImageExtensions.UNKNOWN_FORMAT) {
messageManager.sendMessage(messageId, IStatus.ERROR,
"Image {0} not saved as there is the extension cannot be mapped to a supported image format",
filePath.toPortableString());
return;
}
boolean success = false;
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
imageLoader.save(bos, format);
bos.close();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
if (!file.exists()) {
file.create(bis, IResource.FORCE, null);
} else {
file.setContents(bis, IResource.FORCE, null);
}
success = true;
} catch (Exception ex) {
messageManager.sendMessage(messageId, IStatus.ERROR, "Image {0} not saved. {1}",
filePath.toPortableString(), ex.getMessage());
}
// file.refreshLocal(IResource.DEPTH_ZERO, null);
if (success) {
messageManager.sendMessage(messageId, IStatus.INFO, "Image {0} saved", filePath.toPortableString());
}
}
private ImageData loadSourceImage(int messageId, IPath filePath) {
if (filePath == null) {
throw new IllegalArgumentException("Parameter 'fileSection' must not be null.");
}
ImageData imageData = null;
if (!filePath.isEmpty()) {
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
InputStream is;
try {
is = file.getContents(true);
} catch (CoreException ex) {
messageManager.sendMessage(messageId, ex);
is = null;
}
if (is != null) {
try {
try {
imageData = new ImageData(is);
} catch (SWTException ex) {
messageManager.sendMessage(messageId, IStatus.ERROR,
"Cannot open image file. " + ex.getMessage());
}
} finally {
try {
is.close();
} catch (IOException ex) {
BasePlugin.getInstance().logError("Cannot close input stream for {0}",
new Object[] { filePath }, ex);
}
}
}
}
return imageData;
}
private byte[] loadSourceFile(int messageId, IPath filePath) {
if (filePath == null) {
throw new IllegalArgumentException("Parameter 'filePath' must not be null.");
}
byte[] result;
if (!filePath.isEmpty()) {
try {
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
result = FileUtility.readBytes(file, FileUtility.MAX_SIZE_1MB, true);
} catch (CoreException ex) {
messageManager.sendMessage(messageId, ex);
result = null;
} catch (IllegalArgumentException ex) {
messageManager.sendMessage(messageId, IStatus.ERROR, ex.getMessage());
result = null;
}
} else {
result = null;
}
return result;
}
public boolean convert(ConverterData data) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
ConverterDirection converterDirection;
converterDirection = data.getConverterDirection();
boolean result;
switch (converterDirection) {
case FILES_TO_IMAGE:
result = convertFilesToImage(data);
break;
case IMAGE_TO_FILES:
result = convertImageToFiles(data);
break;
default:
throw new RuntimeException("Unknown converter direction '" + converterDirection + "'.");
}
return result;
}
private boolean convertImageToFiles(ConverterData data) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
if (!data.isValidImage()) {
return false;
}
ImageConverterData imageConverterData;
imageConverterData = data.getImageConverterData();
ImageConverterParameters imageConverterParameters;
imageConverterParameters = imageConverterData.getParameters();
// Setup image data fields.
if (imageConverterData.getImageData() == null) {
// Create empty image data.
PaletteData palette = new PaletteData(255, 255, 255);
data.getImageConverterData().setImageData(new ImageData(320, 256, 8, palette));
imageConverterData.setImageColorHistogram(null);
} else {
ImageColorHistogram imageColorHistogram = new ImageColorHistogram();
imageColorHistogram.analyze(imageConverterData.getImageData());
imageConverterData.setImageColorHistogram(imageColorHistogram);
}
imageConverterData.setImageDataWidth(imageConverterData.getImageData().width);
imageConverterData.setImageDataHeight(imageConverterData.getImageData().height);
imageConverterData.clearTargetFileBytes();
Converter converter;
if (StringUtility.isEmpty(imageConverterParameters.getConverterId())) {
messageManager.sendMessage(ConverterCommonParameters.MessageIds.CONVERTER_ID, IStatus.ERROR,
"No converter selected");
return false;
}
converter = imageConverterData.getConverter();
if (converter == null) {
messageManager.sendMessage(ConverterCommonParameters.MessageIds.CONVERTER_ID, IStatus.ERROR,
"Converter '{0}' is not registered", String.valueOf(imageConverterParameters.getConverterId()));
return false;
}
if (messageManager.containsError()) {
return false;
}
// Default the script if none is specified.
if (StringUtility.isEmpty(imageConverterParameters.getScript())) {
try {
imageConverterParameters.setScript(ConverterScript.getScript(converter.getClass()));
} catch (CoreException ex) {
messageManager.sendMessage(ImageConverterParameters.MessageIds.SCRIPT, ex);
return false;
}
}
try {
// Apply default to conversion parameters.
if (imageConverterParameters.isUseDefaultScript()
|| StringUtility.isEmpty(imageConverterParameters.getScript())) {
String script = ConverterScript.getScript(converter.getClass());
imageConverterParameters.setScript(script);
}
ConverterScript.convertToFileData(converter, imageConverterData);
} catch (CoreException ex) {
messageManager.sendMessage(ConverterCommonParameters.MessageIds.CONVERTER_ID, ex);
return false;
} catch (RuntimeException ex) {
String message = ex.getMessage();
if (message == null) {
message = ex.getClass().getName();
}
messageManager.sendMessage(ImageConverterParameters.MessageIds.SCRIPT, IStatus.ERROR, message);
return false;
}
return true;
}
private boolean convertFilesToImage(ConverterData data) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
if (!data.isValidFile()) {
return false;
}
FilesConverterData filesConverterData;
filesConverterData = data.getFilesConverterData();
filesConverterData.setImageDataValid(false);
filesConverterData.setImageDataWidth(0);
filesConverterData.setImageDataHeight(0);
filesConverterData.setImageData(null);
FilesConverterParameters filesConverterParameters;
filesConverterParameters = filesConverterData.getParameters();
if (filesConverterParameters.getSpacingWidth() < 0) {
messageManager.sendMessage(FilesConverterParameters.MessageIds.SPACING_WIDTH, IStatus.ERROR,
"Spacing width must not be negative. Current value is {0}",
String.valueOf(filesConverterParameters.getSpacingWidth()));
}
if (filesConverterParameters.getColumns() <= 0) {
messageManager.sendMessage(FilesConverterParameters.MessageIds.COLUMNS, IStatus.ERROR,
"Columns count must be positive. Current value is {0}",
String.valueOf(filesConverterParameters.getColumns()));
}
if (filesConverterParameters.getRows() <= 0) {
messageManager.sendMessage(FilesConverterParameters.MessageIds.ROWS, IStatus.ERROR,
"Rows count must be positive. Current value is {0}",
String.valueOf(filesConverterParameters.getRows()));
}
Converter converter;
if (StringUtility.isEmpty(filesConverterParameters.getConverterId())) {
messageManager.sendMessage(ConverterCommonParameters.MessageIds.CONVERTER_ID, IStatus.ERROR,
"No converter selected");
return false;
}
converter = filesConverterData.getConverter();
if (converter == null) {
messageManager.sendMessage(ConverterCommonParameters.MessageIds.CONVERTER_ID, IStatus.ERROR,
"Converter '{0}' is not registered", String.valueOf(filesConverterParameters.getConverterId()));
return false;
}
if (messageManager.containsError()) {
return false;
}
converter.convertToImageDataSize(filesConverterData);
if (filesConverterData.getImageDataWidth() <= 0) {
messageManager.sendMessage(FilesConverterParameters.MessageIds.COLUMNS, IStatus.ERROR,
"Resulting image data with '{0}' is not positive",
String.valueOf(filesConverterData.getImageDataWidth()));
}
if (filesConverterData.getImageDataHeight() <= 0) {
messageManager.sendMessage(FilesConverterParameters.MessageIds.ROWS, IStatus.ERROR,
"Resulting image data height '{0}' is not positive",
String.valueOf(filesConverterData.getImageDataWidth()));
}
int MAX_PIXELS = 1000 * 1000;
int pixels = filesConverterData.getImageDataWidth() * filesConverterData.getImageDataHeight();
if (pixels > MAX_PIXELS) {
messageManager.sendMessage(FilesConverterParameters.MessageIds.ROWS, IStatus.ERROR,
"Resulting image would have {0} pixels and exceed the memory limit of {1} pixels",
String.valueOf(pixels), String.valueOf(MAX_PIXELS));
}
if (messageManager.containsError()) {
return false;
}
// Create index or direct palette and image data.
PaletteData paletteData;
ImageData imageData;
int paletteSize;
paletteSize = filesConverterData.getConverter().getDefinition().getTargetImagePaletteSize();
if (paletteSize > 0) {
// Create 8 bit index palette.
RGB[] paletteColors = new RGB[paletteSize];
RGB[] currentPaletteColors = filesConverterParameters.getPaletteRGBs();
for (int i = 0; i < paletteColors.length; i++) {
if (i < currentPaletteColors.length) {
paletteColors[i] = currentPaletteColors[i];
} else {
paletteColors[i] = new RGB(0, 0, 0);
}
}
filesConverterParameters.setPaletteRGBs(paletteColors);
RGB[] actualPaletteColors = new RGB[paletteColors.length + 1];
System.arraycopy(paletteColors, 0, actualPaletteColors, 0, paletteColors.length);
// The color at index actualPaletteColors.length is used as spacing
// color in order to keep the original palette index order
int spacingColorIndex = paletteColors.length;
actualPaletteColors[spacingColorIndex] = filesConverterParameters.getSpacingColor();
paletteData = new PaletteData(actualPaletteColors);
imageData = new ImageData(filesConverterData.getImageDataWidth(), filesConverterData.getImageDataHeight(),
8, paletteData);
for (int y = 0; y < filesConverterData.getImageDataHeight(); y++) {
for (int x = 0; x < filesConverterData.getImageDataWidth(); x++) {
imageData.setPixel(x, y, spacingColorIndex);
}
}
} else {
// Create 24 bit direct palette.
paletteData = new PaletteData(0xFF0000, 0xFF00, 0xFF);
imageData = new ImageData(filesConverterData.getImageDataWidth(), filesConverterData.getImageDataHeight(),
24, paletteData);
}
filesConverterData.setImageData(imageData);
boolean conversionResult;
try {
conversionResult = converter.convertToImageData(filesConverterData);
} catch (RuntimeException ex) {
GraphicsPlugin.getInstance().logError("Runtime exception during convertFilesToImage()", null, ex);
conversionResult = false;
}
filesConverterData.setImageDataValid(conversionResult);
ImageColorHistogram imageColorHistogram = new ImageColorHistogram();
imageColorHistogram.analyze(imageData);
filesConverterData.setImageColorHistogram(imageColorHistogram);
return conversionResult;
}
}

View File

@ -0,0 +1,285 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import com.wudsn.ide.gfx.model.Aspect;
/**
* Definition of a converter. The definition contains all static meta
* information about the converter. It is normally defined via an extension.
*
*
* For launching application under MacOS see
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=82155 and
* http://www.coderanch.com/t/111494/Mac-OS/launching-Safari-from-Java-App.
*
* @author Peter Dell
*/
public final class ConverterDefinition implements
Comparable<ConverterDefinition> {
// Id
private String id;
private String name;
private List<String> sourceFileExtensions;
private int targetImagePaletteSize;
private Aspect targetImageDisplayAspect;
private List<ConverterSourceFileDefinition> sourceFileDefinitions;
private List<ConverterTargetFileDefinition> targetFileDefinitions;
/**
* Creates an instance. Called by {@link ConverterRegistry} only.
*/
ConverterDefinition() {
sourceFileExtensions = new ArrayList<String>(1);
sourceFileDefinitions = new ArrayList<ConverterSourceFileDefinition>();
targetFileDefinitions = new ArrayList<ConverterTargetFileDefinition>();
}
/**
* Sets the id of the converter. Called by {@link ConverterRegistry} only.
*
* @param id
* The id of the converter, not empty and not <code>null</code>.
*/
final void setId(String id) {
if (id == null) {
throw new IllegalArgumentException(
"Parameter 'id' must not be null.");
}
this.id = id;
}
/**
* Gets the id of the converter.
*
* @return The id of the converter, not empty and not <code>null</code>.
*/
public final String getId() {
if (id == null) {
throw new IllegalStateException("Field 'id' must not be null.");
}
return id;
}
/**
* Sets the name of the converter. Called by {@link ConverterRegistry} only.
*
* @param name
* The name of the converter, not empty and not <code>null</code>
* .
*/
final void setName(String name) {
if (name == null) {
throw new IllegalArgumentException(
"Parameter 'name' must not be null.");
}
this.name = name;
}
/**
* Gets the name of the converter.
*
* @return The name of the converter, not empty and not <code>null</code>.
*/
public final String getName() {
if (name == null) {
throw new IllegalStateException("Field 'name' must not be null.");
}
return name;
}
/**
* Sets the supported source file extensions the converter. Called by
* {@link ConverterRegistry} only.
*
* @param sourceFileExtensions
* The comma separated list of source file extensions in lower
* case characters, may be empty or <code>null</code>.
*
* @since 1.6.0
*/
final void setSourceFileExtensions(String sourceFileExtensions) {
if (sourceFileExtensions == null) {
sourceFileExtensions = "";
}
StringTokenizer st = new StringTokenizer(sourceFileExtensions, ",");
while (st.hasMoreTokens()) {
this.sourceFileExtensions.add(st.nextToken().trim());
}
}
/**
* Determines if a given file extension is supported.
*
* @param fileExtension
* The file extension in lower case letters, may be empty, not
* <code>null</code>.
* @return <code>true</code> if the file extension is supported,
* <code>false</code> otherwise.
*
* @since V1.6.0
*/
public final boolean isSourceFileExtensionSupported(String fileExtension) {
if (fileExtension == null) {
throw new IllegalArgumentException(
"Parameter 'fileExtension' must not be null.");
}
return sourceFileExtensions.contains(fileExtension);
}
/**
* Sets the palette size of the converter. Called by
* {@link ConverterRegistry} only.
*
* @param targetImagePaletteSize
* The palette size of the converter, a positive number if a
* palette is used, 0 for a direct palette.
*/
final void setTargetImagePaletteSize(int targetImagePaletteSize) {
if (targetImagePaletteSize < 0) {
throw new IllegalArgumentException(
"Parameter 'targetImagePaletteSize' must not be negative. Specified value is "
+ targetImagePaletteSize + ".");
}
this.targetImagePaletteSize = targetImagePaletteSize;
}
/**
* Gets the palette size of the target image.
*
* @return The palette size of the target image, a positive number if a
* palette is used, 0 for direct palette.
*/
public final int getTargetImagePaletteSize() {
if (targetImagePaletteSize < 0) {
throw new IllegalStateException(
"Field 'targetImagePaletteSize' must not be negative. Specified value is "
+ targetImagePaletteSize + ".");
}
return targetImagePaletteSize;
}
/**
* Sets the zoom factor of the target image.
*
* @param targetImageDisplayAspect
* The target image zoom factor, not <code>null</code>.
*/
final void setTargetImageDisplayAspect(Aspect targetImageDisplayAspect) {
if (targetImageDisplayAspect == null) {
throw new IllegalArgumentException(
"Parameter 'targetImageDisplayAspect' must not be null.");
}
if (!targetImageDisplayAspect.isValid()) {
throw new IllegalArgumentException(
"Parameter 'targetImageDisplayAspect' must not be invalid.");
}
this.targetImageDisplayAspect = targetImageDisplayAspect;
}
/**
* Gets the zoom factor of the target image.
*
* @return The zoom factor of the target image.
*/
public final Aspect getTargetImageDisplayAspect() {
if (targetImageDisplayAspect == null) {
throw new IllegalStateException(
"Field 'targetImageDisplayAspect' must not be empty.");
}
return targetImageDisplayAspect;
}
/**
* Adds a source file definition. Called by {@link ConverterRegistry} only.
*
* @param sourceFileDefinition
* The source file definition, not <code>null</code>.
*/
final void addSourceFileDefinition(
ConverterSourceFileDefinition sourceFileDefinition) {
if (sourceFileDefinition == null) {
throw new IllegalArgumentException(
"Parameter 'sourceFileDefinition' must not be null.");
}
sourceFileDefinitions.add(sourceFileDefinition);
}
/**
* Gets the unmodifiable list of source file definitions.
*
* @return The unmodifiable list of source file definitions, may be empty,
* not <code>null</code>.
*/
public final List<ConverterSourceFileDefinition> getSourceFileDefinitions() {
return Collections.unmodifiableList(sourceFileDefinitions);
}
/**
* Adds a target file definition. Called by {@link ConverterRegistry} only.
*
* @param targetFileDefinition
* The target file definition, not <code>null</code>.
*/
final void addTargetFileDefinition(
ConverterTargetFileDefinition targetFileDefinition) {
if (targetFileDefinition == null) {
throw new IllegalArgumentException(
"Parameter 'targetFileDefinition' must not be null.");
}
targetFileDefinitions.add(targetFileDefinition);
}
/**
* Gets the unmodifiable list of target file definitions.
*
* @return The unmodifiable list of target file definitions, may be empty,
* not <code>null</code>.
*/
public final List<ConverterTargetFileDefinition> getTargetFileDefinitions() {
return Collections.unmodifiableList(targetFileDefinitions);
}
@Override
public final int compareTo(ConverterDefinition o) {
if (o == null) {
throw new IllegalArgumentException(
"Parameter 'o' must not be null.");
}
if (name == null || o.name == null) {
if (name == null) {
throw new IllegalStateException(
"Field 'name' must not be null for this or for argument.");
}
}
return name.compareTo(o.name);
}
}

View File

@ -0,0 +1,270 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import com.wudsn.ide.base.Texts;
import com.wudsn.ide.base.common.FileUtility;
import com.wudsn.ide.base.common.SequencedProperties;
import com.wudsn.ide.base.common.TextUtility;
import com.wudsn.ide.gfx.GraphicsPlugin;
import com.wudsn.ide.gfx.model.ConverterDirection;
import com.wudsn.ide.gfx.model.GraphicsPropertiesSerializer;
public final class ConverterParameters {
private static final class Attributes {
/**
* Creation is private.
*/
private Attributes() {
}
public static final String CONVERTER_DIRECTION = "converterDirection";
public static final String FILES_CONVERTER_PARAMETERS = "filesConverterParameters";
public static final String IMAGE_CONVERTER_PARAMETERS = "imageConverterParameters";
}
private static final class Defaults {
/**
* Creation is private.
*/
private Defaults() {
}
public static final ConverterDirection CONVERTER_DIRECTION = ConverterDirection.FILES_TO_IMAGE;
}
private ConverterDirection converterDirection;
private FilesConverterParameters filesConverterParameters;
private ImageConverterParameters imageConverterParameters;
public ConverterParameters() {
filesConverterParameters = new FilesConverterParameters();
imageConverterParameters = new ImageConverterParameters();
setDefaults();
}
public void setDefaults() {
converterDirection = Defaults.CONVERTER_DIRECTION;
filesConverterParameters.setDefaults();
imageConverterParameters.setDefaults();
}
public void setConverterDirection(ConverterDirection value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.converterDirection = value;
}
public ConverterDirection getConverterDirection() {
return converterDirection;
}
public ConverterCommonParameters getConverterCommonParameters() {
switch (getConverterDirection()) {
case FILES_TO_IMAGE:
return filesConverterParameters;
case IMAGE_TO_FILES:
return imageConverterParameters;
default:
throw new IllegalStateException("Unknown converter direction "
+ getConverterDirection() + ".");
}
}
public FilesConverterParameters getFilesConverterParameters() {
return filesConverterParameters;
}
public ImageConverterParameters getImageConverterParameters() {
return imageConverterParameters;
}
public void copyTo(ConverterParameters target) {
if (target == null) {
throw new IllegalArgumentException(
"Parameter 'target' must not be null.");
}
target.setConverterDirection(converterDirection);
filesConverterParameters.copyTo(target.getFilesConverterParameters());
imageConverterParameters.copyTo(target.getImageConverterParameters());
}
public boolean equals(ConverterParameters target) {
if (target == null) {
throw new IllegalArgumentException(
"Parameter 'target' must not be null.");
}
boolean result;
result = target.getConverterDirection().equals(converterDirection);
result = result
&& target.getFilesConverterParameters().equals(
filesConverterParameters);
result = result
&& target.getImageConverterParameters().equals(
imageConverterParameters);
return result;
}
public InputStream getContents(String filePath) throws CoreException {
if (filePath == null) {
throw new IllegalArgumentException(
"Parameter 'filePath' must not be null.");
}
GraphicsPropertiesSerializer serializer;
Properties properties;
serializer = new GraphicsPropertiesSerializer();
serialize(serializer);
properties = serializer.getProperties();
ByteArrayOutputStream propertiesStream = new ByteArrayOutputStream();
try {
// ByteArrayOutputStream propertiesStream = new
// ByteArrayOutputStream();
properties
.store(propertiesStream, "WUDSN IDE Converter Parameters");
propertiesStream.close();
// Iterator<ImageWriter> iterator = ImageIO
// .getImageWritersBySuffix("png");
//
// if (!iterator.hasNext()) {
// throw new RuntimeException("No image writer for suffix 'png'");
// }
//
// ImageWriter imagewriter = iterator.next();
// imagewriter.setOutput(ImageIO
// .createImageOutputStream(resourceStream));
//
// // Create & populate metadata
// PNGMetadata metadata = new PNGMetadata();
// metadata.tEXt_keyword.add("WUDSN");
// metadata.tEXt_text.add(new
// String(propertiesStream.toByteArray()));//
//
// // Render the PNG to memory
// BufferedImage bufferedImage = new BufferedImage(imageData.width,
// imageData.height, BufferedImage.TYPE_INT_RGB);
// for (int y = 0; y < imageData.height; y++) {
// for (int x = 0; x < imageData.width; x++) {
// int pixel;
// RGB rgb;
//
// pixel = imageData.getPixel(x, y);
// rgb = imageData.palette.getRGB(pixel);
// bufferedImage.setRGB(x, y, rgb.red << 16 | rgb.green << 8
// | rgb.blue);
// }
// }
//
// // Build the image container, set the metadata and write the
// // container.
// IIOImage iioImage = new IIOImage(bufferedImage, null, null);
// iioImage.setMetadata(metadata); // Attach the metadata
// imagewriter.write(null, iioImage, null);
} catch (IOException ex) {
// ERROR: Cannot write content of file '{0}'.
throw new CoreException(new Status(IStatus.ERROR, GraphicsPlugin.ID,
TextUtility.format(Texts.MESSAGE_E212, filePath), ex));
}
return new ByteArrayInputStream(propertiesStream.toByteArray());
}
private void serialize(GraphicsPropertiesSerializer serializer) {
if (serializer == null) {
throw new IllegalArgumentException(
"Parameter 'serializer' must not be null.");
}
serializer
.writeEnum(Attributes.CONVERTER_DIRECTION, converterDirection);
filesConverterParameters.serialize(serializer,
Attributes.FILES_CONVERTER_PARAMETERS);
imageConverterParameters.serialize(serializer,
Attributes.IMAGE_CONVERTER_PARAMETERS);
}
public void read(IFile file) throws CoreException {
if (file == null) {
throw new IllegalArgumentException(
"Parameter 'file' must not be null.");
}
byte[] content;
content = FileUtility.readBytes(file, FileUtility.MAX_SIZE_UNLIMITED,
false);
SequencedProperties properties = new SequencedProperties();
try {
properties.load(new ByteArrayInputStream(content));
} catch (IOException ex) {
// ERROR: Cannot read content of file '{0}'.
throw new CoreException(new Status(IStatus.ERROR, GraphicsPlugin.ID,
TextUtility.format(Texts.MESSAGE_E206, file.getFullPath()
.toOSString()), ex));
}
GraphicsPropertiesSerializer serializer;
serializer = new GraphicsPropertiesSerializer();
serializer.getProperties().putAll(properties);
deserialize(serializer);
GraphicsPlugin.getInstance().log("ConverterParameters.read({0}):{1}",
new Object[] { file, serializer.getProperties() });
}
private void deserialize(GraphicsPropertiesSerializer serializer) {
if (serializer == null) {
throw new IllegalArgumentException(
"Parameter 'serializer' must not be null.");
}
converterDirection = serializer.readEnum(
Attributes.CONVERTER_DIRECTION, Defaults.CONVERTER_DIRECTION,
ConverterDirection.class);
filesConverterParameters.deserialize(serializer,
Attributes.FILES_CONVERTER_PARAMETERS);
imageConverterParameters.deserialize(serializer,
Attributes.IMAGE_CONVERTER_PARAMETERS);
}
}

View File

@ -0,0 +1,305 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import com.wudsn.ide.gfx.model.AspectUtility;
import com.wudsn.ide.gfx.model.ConverterDirection;
/**
* Registry for converters, based on the extension points
* {@value ConverterRegistry#CONVERTERS}.
*
* @author Peter Dell
*
*/
public final class ConverterRegistry {
/**
* The id of the extension point which provides the converters.
*/
private static final String CONVERTERS = "com.wudsn.ide.gfx.converters";
/**
* Maximum number of source files.
*/
public static final int MAX_SOURCE_FILES = 10;
/**
* Maximum number of target files.
*/
public static final int MAX_TARGET_FILES = 10;
/**
* The registered converter definitions.
*/
private List<ConverterDefinition> filesToImageConverterDefinitionList;
private List<ConverterDefinition> imageToFilesConverterDefinitionList;
/**
* The cached map of converter instances.
*/
private Map<String, Converter> converterMap;
/**
* Creation is public.
*/
public ConverterRegistry() {
filesToImageConverterDefinitionList = Collections.emptyList();
imageToFilesConverterDefinitionList = Collections.emptyList();
converterMap = Collections.emptyMap();
}
/**
* Initializes the list of available converters.
*/
public void init() {
filesToImageConverterDefinitionList = new ArrayList<ConverterDefinition>();
imageToFilesConverterDefinitionList = new ArrayList<ConverterDefinition>();
converterMap = new TreeMap<String, Converter>();
IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = extensionRegistry
.getExtensionPoint(CONVERTERS);
if (extensionPoint == null) {
throw new IllegalStateException("Extension point '" + CONVERTERS
+ "' is not defined.");
}
IExtension[] extensions = extensionPoint.getExtensions();
for (IExtension extension : extensions) {
IConfigurationElement[] converterGroupElements = extension
.getConfigurationElements();
for (IConfigurationElement converterGroupElement : converterGroupElements) {
IConfigurationElement[] converterElements = converterGroupElement
.getChildren("converter");
for (IConfigurationElement converterElement : converterElements) {
ConverterDefinition converterDefinition;
converterDefinition = new ConverterDefinition();
converterDefinition.setId(converterElement
.getAttribute("id"));
converterDefinition.setName(converterElement
.getAttribute("name"));
converterDefinition
.setSourceFileExtensions(converterElement
.getAttribute("sourceFileExtensions"));
converterDefinition.setTargetImagePaletteSize(Integer
.parseInt(converterElement
.getAttribute("targetImagePaletteSize")));
converterDefinition
.setTargetImageDisplayAspect(AspectUtility.fromString(converterElement
.getAttribute("targetImageDisplayAspect")));
IConfigurationElement[] sourceFileElements = converterElement
.getChildren("sourceFile");
int i = 0;
for (IConfigurationElement sourceFileElement : sourceFileElements) {
ConverterSourceFileDefinition sourceFileDefinition;
sourceFileDefinition = new ConverterSourceFileDefinition();
sourceFileDefinition.setSourceFileId(i);
sourceFileDefinition.setLabel(sourceFileElement
.getAttribute("label"));
converterDefinition
.addSourceFileDefinition(sourceFileDefinition);
i++;
}
IConfigurationElement[] targetFileElements = converterElement
.getChildren("targetFile");
i = 0;
for (IConfigurationElement targetFileElement : targetFileElements) {
ConverterTargetFileDefinition targetFileDefinition;
targetFileDefinition = new ConverterTargetFileDefinition();
targetFileDefinition.setSourceFileId(i);
targetFileDefinition.setLabel(targetFileElement
.getAttribute("label"));
converterDefinition
.addTargetFileDefinition(targetFileDefinition);
i++;
}
// If there is a source file, it is a files to image
// converter.
if (!converterDefinition.getSourceFileDefinitions()
.isEmpty()) {
filesToImageConverterDefinitionList
.add(converterDefinition);
}
// If there is a target file, it is a files to image
// converter.
if (!converterDefinition.getTargetFileDefinitions()
.isEmpty()) {
imageToFilesConverterDefinitionList
.add(converterDefinition);
}
addConverter(converterElement, converterDefinition);
}
}
}
// Create a sorted, unmodifiable copy.
filesToImageConverterDefinitionList = new ArrayList<ConverterDefinition>(
filesToImageConverterDefinitionList);
Collections.sort(filesToImageConverterDefinitionList);
filesToImageConverterDefinitionList = Collections
.unmodifiableList(filesToImageConverterDefinitionList);
// Create a sorted, unmodifiable copy.
imageToFilesConverterDefinitionList = new ArrayList<ConverterDefinition>(
imageToFilesConverterDefinitionList);
Collections.sort(imageToFilesConverterDefinitionList);
imageToFilesConverterDefinitionList = Collections
.unmodifiableList(imageToFilesConverterDefinitionList);
// Create an unmodifiable copy.
converterMap = Collections.unmodifiableMap(converterMap);
}
/**
* Adds a new converter.
*
* @param configurationElement
* The configuration element used as class instance factory, not
* <code>null</code>.
*
* @param converterDefinition
* The converter definition, not <code>null</code>.
*/
private void addConverter(IConfigurationElement configurationElement,
ConverterDefinition converterDefinition) {
if (configurationElement == null) {
throw new IllegalArgumentException(
"Parameter 'configurationElement' must not be null.");
}
if (converterDefinition == null) {
throw new IllegalArgumentException(
"Parameter 'converterDefinition' must not be null.");
}
String id = converterDefinition.getId();
Converter converter;
try {
converter = (Converter) configurationElement
.createExecutableExtension("id");
} catch (CoreException ex) {
throw new RuntimeException("Cannot instantiate converter '" + id
+ "'.", ex);
}
converter.setDefinition(converterDefinition);
converter = converterMap.put(id, converter);
if (converter != null) {
throw new RuntimeException("Converter id '" + id
+ "' is already registered to class '"
+ converter.getClass().getName() + "'.");
}
}
/**
* Gets the unmodifiable list of converter definitions, sorted by their id.
*
* @param converterDirection
* The converter direction, not <code>null</code>.
*
* @return The unmodifiable list of converter definitions, sorted by their
* id, not empty and not <code>null</code>.
*/
public List<ConverterDefinition> getDefinitions(
ConverterDirection converterDirection) {
if (converterDirection == null) {
throw new IllegalArgumentException(
"Parameter 'converterDirection' must not be null.");
}
switch (converterDirection) {
case FILES_TO_IMAGE:
return filesToImageConverterDefinitionList;
case IMAGE_TO_FILES:
return imageToFilesConverterDefinitionList;
default:
throw new IllegalArgumentException("Unknown converter directtion "
+ converterDirection + ".");
}
}
/**
* Gets the converter definition for an id.
*
* @param converterId
* The converter id, may be empty, not <code>null</code>.
* @param converterDirection
* The direction of the converter, not <code>null</code>.
*
* @return The converter definition or <code>null</code>.
*/
public ConverterDefinition getDefinition(String converterId,
ConverterDirection converterDirection) {
if (converterId == null) {
throw new IllegalArgumentException(
"Parameter 'converterId' must not be null.");
}
List<ConverterDefinition> converterDefinitionList = getDefinitions(converterDirection);
for (ConverterDefinition converterDefinition : converterDefinitionList) {
if (converterDefinition.getId().equals(converterId)) {
return converterDefinition;
}
}
return null;
}
/**
* Gets the converter for a given id. Instances of {@link Converter} are
* stateless singletons within the plugin.
*
* @param converterId
* The converter id, not <code>null</code>.
*
* @return The converter or <code>null</code>.
*/
public Converter getConverter(String converterId) {
if (converterId == null) {
throw new IllegalArgumentException(
"Parameter 'converterId' must not be null.");
}
Converter result;
synchronized (converterMap) {
result = converterMap.get(converterId);
}
return result;
}
}

View File

@ -0,0 +1,162 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.io.InputStream;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.RhinoException;
import org.mozilla.javascript.Scriptable;
import com.wudsn.ide.base.common.FileUtility;
import com.wudsn.ide.gfx.GraphicsPlugin;
/**
* Converter script utility class.
*
* @author Peter Dell
*
* @since 1.6.0
*/
public final class ConverterScript {
public static void convertToFileData(Converter converter, ImageConverterData data) throws CoreException {
// Collect the arguments into a single string.
String script = data.getParameters().getScript();
ConverterScriptData converterScriptData = data.getConverterScriptData();
ContextFactory contextFactory = ContextFactory.getGlobal();
Context context = null;
Scriptable scope = null;
try {
if (!script.equals(converterScriptData.getCompiledScript())) {
if (converterScriptData.getCompiledContext() != null && Context.getCurrentContext() != null) {
Context.exit();
}
// Creates and enters a new Context. The Context stores
// information
// about the execution environment of a script.
context = contextFactory.enterContext();
scope = context.initStandardObjects();
context.setOptimizationLevel(9);
context.evaluateString(scope, script, "Line ", 1, null);
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed. Returns
// a scope object that we use in later calls.
converterScriptData.setCompiledScript(script);
converterScriptData.setCompiledContext(context);
converterScriptData.setCompiledScope(scope);
} else {
// Restore the previous context.
context = converterScriptData.getCompiledContext();
contextFactory.enterContext(context);
scope = converterScriptData.getCompiledScope();
}
// Set global variables.
ConverterConsole converterConsole = GraphicsPlugin.getInstance().getConverterConsole();
scope.put("Console", scope, Context.toObject(converterConsole, scope));
// Call function
converterScriptData.setErrorLineNumber(-1);
String functionName = "convertToFileData";
Object functionObject = scope.get(functionName, scope);
if (functionObject == null) {
throw new CoreException(new Status(IStatus.ERROR, GraphicsPlugin.ID, "'" + functionName
+ "' is undefined."));
}
if (!(functionObject instanceof Function)) {
throw new CoreException(new Status(IStatus.ERROR, GraphicsPlugin.ID, "'" + functionName
+ "' is not a function."));
}
Object functionArgs[] = { Context.toObject(data, scope) };
Function function = (Function) functionObject;
function.call(context, scope, scope, functionArgs);
} catch (RhinoException ex) {
converterScriptData.setErrorLineNumber(ex.lineNumber());
String message = getMessageString(ex.details());
String lineSource = getMessageString(ex.lineSource());
throw new CoreException(new Status(IStatus.ERROR, GraphicsPlugin.ID, "Error in script line "
+ ex.lineNumber() + ": " + message + " " + lineSource, ex));
} finally {
// Exit from the context. Remove the context association to the
// current thread.
if (Context.getCurrentContext() != null) {
Context.exit();
}
}
}
/**
* Converts a string to message format (not <code>null</code>, no tabs).
*
* @param string
* The string, or <code>null</code>.
* @return The message string, may be empty, not <code>null</code>.
*/
private static String getMessageString(String string) {
String result;
if (string != null) {
result = string.replace('\t', ' ');
} else {
result = "";
}
return result;
}
/**
* Gets the script associated with a compiler class.
*
* @param converterClass
* The of the converter, not <code>null</code>.
* @return The script for the converter, may be empty, not <code>null</code>
* .
* @throws CoreException
* In case there is an error while reading an existing script.
*/
public static String getScript(Class<? extends Converter> converterClass) throws CoreException {
if (converterClass == null) {
throw new IllegalArgumentException("Parameter 'converterClass' must not be null.");
}
String result;
String converterScriptFileName = "/" + converterClass.getName().replace('.', '/') + ".js";
InputStream inputStream = converterClass.getResourceAsStream(converterScriptFileName);
if (inputStream != null) {
result = FileUtility.readString(converterScriptFileName, inputStream, FileUtility.MAX_SIZE_UNLIMITED);
} else {
result = "";
}
return result;
}
}

View File

@ -0,0 +1,121 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
/**
* Container for a compiled converter scripts and its context.
*
* @author Peter Dell
* @since 1.6.6
*/
public final class ConverterScriptData {
private String compiledScript;
private Context compiledContext;
private Scriptable compiledScope;
private int errorLineNumber;
/**
* Gets the compiled script for which the compiled context and scope are
* cached.
*
* @return The compiled script, maybe be empty, not <code>null</code>.
*/
public String getCompiledScript() {
return compiledScript;
}
/**
* Sets the compiled script for which the compiled context and scope are
* cached.
*
* @param compiledScript
* The compiled script, may be empty, not <code>null</code>.
*/
public void setCompiledScript(String compiledScript) {
if (compiledScript == null) {
throw new IllegalArgumentException("Parameter 'compiledScript' must not be null.");
}
this.compiledScript = compiledScript;
}
/**
* Gets the compiled context which was created for the compiled script.
*
* @return The compiled context or <code>null</code>.
*/
public Context getCompiledContext() {
return compiledContext;
}
/**
* Sets the compiled context which was created for the compiled script.
*
* @param compiledContext
* The compiled context or <code>null</code>.
*/
public void setCompiledContext(Context compiledContext) {
this.compiledContext = compiledContext;
}
/**
* Gets the compiled scope which was created for the compiled script.
*
* @return The compiled context or <code>null</code>.
*/
public Scriptable getCompiledScope() {
return compiledScope;
}
/**
* Sets the compiled scope which was created for the compiled script.
*
* @param compiledScope
* The compiled scope or <code>null</code>.
*/
public void setCompiledScope(Scriptable compiledScope) {
this.compiledScope = compiledScope;
}
/**
* Set the line number of the first error that occurred in the script.
*
* @param errorLineNumber
* The line number of the first error that occurred in the
* script, a positive integer or <code>-1</code> if there is
* no error.
*/
public void setErrorLineNumber(int errorLineNumber) {
this.errorLineNumber = errorLineNumber;
}
/**
* Gets the line number of the first error that occurred in the script.
*
* @return The line number of the first error that occurred in the script,a
* positive integer or <code>-1</code> if there is no error.
*/
public int geErrorLineNumber() {
return errorLineNumber;
}
}

View File

@ -0,0 +1,45 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
public final class ConverterSourceFileDefinition {
private int sourceFileId;
private String label;
ConverterSourceFileDefinition() {
}
public int getSourceFileId() {
return sourceFileId;
}
final void setSourceFileId(int sourceFileId) {
this.sourceFileId = sourceFileId;
}
public String getLabel() {
return label;
}
final void setLabel(String label) {
this.label = label;
}
}

View File

@ -0,0 +1,46 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
public final class ConverterTargetFileDefinition {
private int sourceFileId;
private String label;
ConverterTargetFileDefinition() {
}
public int getSourceFileId() {
return sourceFileId;
}
final void setSourceFileId(int sourceFileId) {
this.sourceFileId = sourceFileId;
}
public String getLabel() {
return label;
}
final void setLabel(String label) {
this.label = label;
}
}

View File

@ -0,0 +1,212 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.util.ArrayList;
import java.util.List;
import com.wudsn.ide.base.common.HexUtility;
import com.wudsn.ide.base.common.NumberUtility;
import com.wudsn.ide.gfx.GraphicsPlugin;
import com.wudsn.ide.gfx.model.ConverterDirection;
import com.wudsn.ide.gfx.model.ConverterMode;
public final class FilesConverterData extends ConverterCommonData {
private FilesConverterParameters parameters;
private List<byte[]> sourceFilesBytes;
private boolean imageDataValid;
FilesConverterData(ConverterData converterData) {
super(converterData);
this.parameters = converterData.getParameters()
.getFilesConverterParameters();
sourceFilesBytes = new ArrayList<byte[]>(0);
}
public FilesConverterParameters getParameters() {
return parameters;
}
/**
* Gets the converter for a converter id specified in the parameters.
* Instances of {@link Converter} are stateless singletons within the
* plugin.
*
* @return The converter or <code>null</code>.
*/
public Converter getConverter() {
ConverterRegistry converterRegistry;
Converter converter;
converterRegistry = GraphicsPlugin.getInstance().getConverterRegistry();
converter = converterRegistry.getConverter(parameters.getConverterId());
return converter;
}
public int getTargetImagePaletteSize() {
ConverterRegistry converterRegistry;
ConverterDefinition converterDefinition;
int result;
converterRegistry = GraphicsPlugin.getInstance().getConverterRegistry();
converterDefinition = converterRegistry.getDefinition(
parameters.getConverterId(), ConverterDirection.FILES_TO_IMAGE);
if (converterDefinition != null) {
result = converterDefinition.getTargetImagePaletteSize();
} else {
result = 0;
}
return result;
}
@Override
public boolean isCreateConversionEnabled() {
return converterData.isValid()
&& converterData.getConverterMode() == ConverterMode.RAW_FILE;
}
@Override
public boolean isValid() {
return converterData.isValidFile();
}
@Override
public boolean isRefreshEnabled() {
return converterData.isValidFile();
}
@Override
public void clear() {
super.clear();
sourceFilesBytes.clear();
}
public void setSourceFileBytes(int sourceFileId, byte[] bytes) {
if (sourceFileId < 0) {
throw new IllegalArgumentException(
"Parameter 'sourceFileId' must not be negative. Specified value is "
+ sourceFileId + ".");
}
while (sourceFilesBytes.size() <= sourceFileId) {
sourceFilesBytes.add(null);
}
sourceFilesBytes.set(sourceFileId, bytes);
}
public byte[] getSourceFileBytes(int sourceFileId) {
if (sourceFileId < 0) {
throw new IllegalArgumentException(
"Parameter 'sourceFileId' must not be negative. Specified value is "
+ sourceFileId + ".");
}
byte[] bytes;
if (sourceFileId < sourceFilesBytes.size()) {
bytes = sourceFilesBytes.get(sourceFileId);
} else {
bytes = null;
}
return bytes;
}
public void setImageDataValid(boolean imageDataValid) {
this.imageDataValid = imageDataValid;
}
public boolean isImageDataValid() {
return imageDataValid;
}
public boolean isSaveImageEnabled() {
return converterData.isValidFile()&& isImageDataValid();
}
/**
* Gets a byte from the source file, taking it offset from the parameter
* into account plus the relative offset of the conversion routine.
*
* @param sourceFileId
* The id of the source file, a non-negative integer.
* @param offset
* The relative object of the conversion routine, a non-negative
* integer.
* @return The byte as integer or <code>-1</code> to indicate that the
* offset is outside of the file.
*/
public int getSourceFileByte(int sourceFileId, int offset) {
if (sourceFileId >= sourceFilesBytes.size()) {
return -1;
}
byte[] sourceFileBytes = sourceFilesBytes.get(sourceFileId);
if (sourceFileBytes == null) {
return -1;
}
offset = offset + parameters.getSourceFile(sourceFileId).getOffset();
if (offset < 0 || offset >= sourceFileBytes.length) {
return -1;
}
int value = sourceFileBytes[offset] & 0xff;
return value;
}
public void setPalettePixel(int x, int y, int color) {
try {
imageData.setPixel(x, y, color);
} catch (RuntimeException ex) {
GraphicsPlugin
.getInstance()
.logError(
"Error setting palette pixel at ({0}, {1}) to color {2}. Image size is {3},{4}",
new String[] {
NumberUtility.getLongValueDecimalString(x),
NumberUtility.getLongValueDecimalString(y),
HexUtility.getLongValueHexString(color),
NumberUtility
.getLongValueDecimalString(imageData.width),
NumberUtility
.getLongValueDecimalString(imageData.height) },
ex);
}
}
public void setDirectPixel(int x, int y, int color) {
try {
imageData.setPixel(x, y, color);
} catch (RuntimeException ex) {
GraphicsPlugin
.getInstance()
.logError(
"Error setting direct pixel at ({0}, {1}) to color {2}. Image size is {3},{4}",
new String[] {
NumberUtility.getLongValueDecimalString(x),
NumberUtility.getLongValueDecimalString(y),
HexUtility.getLongValueHexString(color),
NumberUtility
.getLongValueDecimalString(imageData.width),
NumberUtility
.getLongValueDecimalString(imageData.height) },
ex);
}
}
}

View File

@ -0,0 +1,293 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.util.Iterator;
import java.util.List;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.GraphicsPlugin;
import com.wudsn.ide.gfx.converter.atari8bit.LinearBitMapGraphics8Converter;
import com.wudsn.ide.gfx.model.ConverterDirection;
/**
* This class is based on the excellent open source
* "First Atari Image Library (FAIL)". Thanks to the creators to FAIL: Piotr
* Fusik, Adrian Matoga and Pawel Szewczyk for their support. You can find FAIL
* on sourceforge "http://fail.sourceforge.net".
*
* @author Peter Dell
*
*/
public final class FilesConverterDataLogic {
/**
* Helper class to detect the support binary file formats by their
* extension. The extension have to be defined with lower case characters.
*
* @author Peter Dell
*/
public static final class FileExtensions {
// C64 font with 2 bytes load address
public static final String _64c = "64c";
// 80x192, 256 colors, interlaced
// @since FAIL 1.0.0
public static final String AP3 = "ap3";
// Any Point, Any Color; 80x96, 256 colors, interlaced
// @since FAIL 1.0.0
public static final String APC = "apc";
// 8x8 charset, mono or multicolor
// @since FAIL 1.0.0
public static final String CHR = "chr";
// Champions' Interlace; 160x192, compressed
// @since FAIL 1.0.0
public static final String CCI = "cci";
// Champions' Interlace; 160x192
// @since FAIL 1.0.0
public static final String CIN = "cin";
// Trzmiel; 320x192, mono, compressed
// @since FAIL 1.0.0
public static final String CPR = "cpr";
// Standard 8x8 font, mono
// @since FAIL 1.0.0
public static final String FNT = "fnt";
// Gephard Hires Graphics; up to 320x200, mono
// @since FAIL 1.0.1
public static final String GHG = "ghg";
// Standard 320x192, mono
// @since FAIL 1.0.0
public static final String GR8 = "gr8";
// Standard 80x192, grayscale
// @since FAIL 1.0.0
public static final String GR9 = "gr9";
// Hard Interlace Picture; 160x200, grayscale
// @since FAIL 1.0.0
public static final String HIP = "hip";
// Hires 256x239, 3 colors, interlaced
// @since FAIL 1.0.0
public static final String HR = "hr";
// Hires 320x200, 5 colors, interlaced
// @since FAIL 1.0.1
public static final String HR2 = "hr2";
// APAC 80x192, 256 colors interlaced
// @since FAIL 1.0.0
public static final String ILC = "ilc";
// Interlace Picture 160x200, 7 colors, interlaced
// @since FAIL 1.0.0
public static final String INP = "inp";
// INT95a, up to 160x239, 16 colors, interlaced
// @since FAIL 1.0.0
public static final String INT = "int";
// McPainter; 160x200, 16 colors, interlaced
// @since FAIL 1.0.1
public static final String MCP = "mcp";
// Micropainter 160x192, 4 colors
// @since FAIL 1.0.0
public static final String MIC = "mic";
// Koala MicroIllustrator; 160x192, 4 colors, compressed
// @since FAIL 1.0.0
public static final String PIC = "pic";
// Plama 256; 80x96, 256 colors
// @since FAIL 1.0.0
public static final String PLM = "plm";
// Rocky Interlace Picture; up to 160x239
// @since FAIL 1.0.0
public static final String RIP = "rip";
// C64 sprites
// Can be mono or multi color.
public static final String SPR = "spr";
// 16x16 font, mono
// @since FAIL 1.0.0
public static final String SXS = "sxs";
// Taquart Interlace Picture; up to 160x119
// @since FAIL 1.0.0
public static final String TIP = "tip";
// TODO Fail 1.1.0
// Fixed decoding of ILC, AP3, RIP, PIC, CPR, HIP and CIN.
// Added support for MCH, IGE, 256, AP2, JGP, DGP, ESC, PZM, IST and RAW.
// MCH IGE 256 AP2 JGP DGP ESC PZM IST RAW
// 256:: 80x96, 256 colors.
// AP2:: 80x96, 256 colors.
//
// DGP:: "DigiPaint", 80x192, 256 colors, interlaced.
// ESC:: "EscalPaint", 80x192, 256 colors, interlaced.
// IGE:: "Interlace Graphics Editor", 128x96, 16 colors, interlaced.
//
// IST:: "Interlace Studio", 160x200, interlaced.
// JGP:: "Jet Graphics Planner", 8x16 tiles, 4 colors.
// MCH:: Up to 192x240, 128 colors.
// PZM:: "EscalPaint", 80x192, 256 colors, interlaced.
// RAW:: "XL-Paint MAX", 160x192, 16 colors, interlaced.
// fail.h: #define FAIL_WIDTH_MAX 320 => 384, used in RIP
//
// /* Limits. */
// #define FAIL_IMAGE_MAX 30000
// #define FAIL_WIDTH_MAX 384
// #define FAIL_HEIGHT_MAX 240
// #define FAIL_PALETTE_MAX 768
// #define FAIL_PIXELS_MAX (FAIL_WIDTH_MAX * FAIL_HEIGHT_MAX * 3)
}
FilesConverterDataLogic() {
}
public void applyDefaults(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
FilesConverterParameters parameters;
Converter converter;
parameters = data.getParameters();
converter = data.getConverter();
// Take defaults from the definition.
if (converter != null) {
int targetImagePaletteSize = converter.getDefinition()
.getTargetImagePaletteSize();
RGB[] rgbs;
if (targetImagePaletteSize > 0) {
rgbs = new RGB[targetImagePaletteSize];
for (int i = 0; i < targetImagePaletteSize; i++) {
int brightness = (255 * i) / (targetImagePaletteSize - 1);
RGB rgb = new RGB(brightness, brightness, brightness);
rgbs[i] = rgb;
}
} else {
rgbs = new RGB[0];
}
parameters.setPaletteRGBs(rgbs);
parameters.setDisplayAspect(converter.getDefinition()
.getTargetImageDisplayAspect());
}
}
/**
* Find the most suitable converter, apply its defaults and preset image
* dimensions and colors based on the input file. In case of compressed
* images, the source file in the data container is replaced by the unpacked
* content. This leads to unwanted effect during reload which can only be
* removed by the introduction of separate converters for these cases.
*
* @param data
* The file converter data, not <code>null</code>.
* @param bytes
* The file content of the input file, not <code>null</code>.
* @param fileExtension
* The file extension of the input file, may be empty, not
* <code>null</code>.
*/
public void findDefaultFileConverter(FilesConverterData data, byte[] bytes,
String fileExtension) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
if (fileExtension == null) {
throw new IllegalArgumentException(
"Parameter 'fileExtension' must not be null.");
}
int columns;
int rows;
FilesConverterParameters parameters = data.getParameters();
ConverterRegistry converterRegistry = GraphicsPlugin.getInstance()
.getConverterRegistry();
List<ConverterDefinition> converterDefinitions = converterRegistry
.getDefinitions(ConverterDirection.FILES_TO_IMAGE);
// Try to match file extensions and content.
boolean converted = false;
Iterator<ConverterDefinition> i = converterDefinitions.iterator();
while (i.hasNext() && !converted) {
ConverterDefinition converterDefinition = i.next();
if (converterDefinition
.isSourceFileExtensionSupported(fileExtension)) {
Converter converter = converterRegistry
.getConverter(converterDefinition.getId());
if (converter.canConvertToImage(bytes)) {
converter.convertToImageSizeAndPalette(data, bytes);
converted = true;
}
}
}
// Ignore file extension and try to match content only.
if (!converted) {
i = converterDefinitions.iterator();
while (i.hasNext() && !converted) {
ConverterDefinition converterDefinition = i.next();
Converter converter = converterRegistry
.getConverter(converterDefinition.getId());
if (converter.canConvertToImage(bytes)) {
converter.convertToImageSizeAndPalette(data, bytes);
converted = true;
}
}
}
// If nothing matched, display as hires bitmap.
if (!converted) {
data.getParameters().setConverterId(
LinearBitMapGraphics8Converter.class.getName());
applyDefaults(data);
columns = 40;
rows = (bytes.length + columns - 1) / columns;
parameters.setColumns(columns);
parameters.setRows(rows);
}
}
}

View File

@ -0,0 +1,550 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.GraphicsPlugin;
import com.wudsn.ide.gfx.model.ConverterDirection;
import com.wudsn.ide.gfx.model.GraphicsPropertiesSerializer;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.PaletteType;
public final class FilesConverterParameters extends ConverterCommonParameters {
/**
* Names of the attributes.
*
* @author Peter Dell
*
*/
public static final class Attributes {
/**
* Creation is private.
*/
private Attributes() {
}
public static final String SOURCE_FILES = "sourceFiles";
public static final String SOURCE_FILE_PATH = "path";
public static final String SOURCE_FILE_OFFSET = "offset";
public static final String IMAGE_FILE_PATH = "imageFilePath";
public static final String COLUMNS = "columns";
public static final String ROWS = "rows";
public static final String SPACING_COLOR = "spacingColor";
public static final String SPACING_WIDTH = "spacingWidth";
public static final String PIXEL_TYPE = "pixelType";
public static final String PALETTE = "palette";
public static final String PALETTE_TYPE = "paletteType";
public static final String PALETTE_COLORS = "paletteRGBs";
}
/**
* Defaults of the attributes.
*
* @author Peter Dell
*
*/
private static final class Defaults {
/**
* Creation is private.
*/
private Defaults() {
}
public static final String SOURCE_FILE_PATH = "";
public static final int SOURCE_FILE_OFFSET = 0;
public static final String IMAGE_FILE_PATH = "";
public static final int COLUMNS = 40;
public static final int ROWS = 24;
public static final RGB SPACING_COLOR = new RGB(0, 0, 128);
public static final int SPACING_WIDTH = 0;
public static final PaletteType PALETTE_TYPE = PaletteType.ATARI_DEFAULT;
public static final Palette PALETTE = Palette.HIRES_1;
public static final RGB[] PALETTE_COLORS = new RGB[0];
}
/**
* Message ids of the attributes.
*
* @author Peter Dell
*
*/
public static final class MessageIds {
/**
* Creation is private.
*/
private MessageIds() {
}
public static final int SOURCE_FILE_PATH = 1010;
public static final int SOURCE_FILE_OFFSET = 1020;
public static final int IMAGE_FILE_PATH = 1030;
public static final int SPACING_COLOR = 1100;
public static final int SPACING_WIDTH = 1101;
public static final int COLUMNS = 1102;
public static final int ROWS = 1103;
}
/**
* A source file.
*
* @author Peter Dell
*
*/
public static final class SourceFile {
private int id;
private String path;
private int offset;
public SourceFile(int id) {
this.id = id;
path = Defaults.SOURCE_FILE_PATH;
offset = Defaults.SOURCE_FILE_OFFSET;
}
public int getId() {
return id;
}
public int getPathMessageId() {
return MessageIds.SOURCE_FILE_PATH + id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
if (path == null) {
throw new IllegalArgumentException(
"Parameter 'path' must not be null.");
}
this.path = path;
}
public int getOffsetMessageId() {
return MessageIds.SOURCE_FILE_OFFSET + id;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
throw new IllegalArgumentException(
"Parameter 'obj' must not be null.");
}
SourceFile other = (SourceFile) obj;
return other.id == this.id && other.path.equals(this.path)
&& other.offset == this.offset;
}
@Override
public int hashCode() {
return id + 7 * path.hashCode() + 17 * offset;
}
}
private int sourceFilesSize;
private List<SourceFile> sourceFiles;
private String imageFilePath;
private int columns;
private int rows;
private RGB spacingColor;
private int spacingWidth;
private PaletteType paletteType;
private Palette palette;
private RGB[] paletteRGBs;
FilesConverterParameters() {
int size = ConverterRegistry.MAX_SOURCE_FILES;
this.sourceFiles = new ArrayList<SourceFile>(size);
for (int i = 0; i < size; i++) {
this.sourceFiles.add(new SourceFile(i));
}
setDefaults();
}
@Override
public void setDefaults() {
super.setDefaults();
for (SourceFile sourceFile : sourceFiles) {
sourceFile.setPath(Defaults.SOURCE_FILE_PATH);
sourceFile.setOffset(Defaults.SOURCE_FILE_OFFSET);
}
imageFilePath = Defaults.IMAGE_FILE_PATH;
columns = Defaults.COLUMNS;
rows = Defaults.ROWS;
spacingColor = Defaults.SPACING_COLOR;
spacingWidth = Defaults.SPACING_WIDTH;
paletteType = Defaults.PALETTE_TYPE;
palette = Defaults.PALETTE;
paletteRGBs = Defaults.PALETTE_COLORS;
}
@Override
public void setConverterId(String value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.converterId = value;
ConverterDefinition converterDefinition;
converterDefinition = GraphicsPlugin.getInstance()
.getConverterRegistry()
.getDefinition(converterId, ConverterDirection.FILES_TO_IMAGE);
if (converterDefinition != null) {
sourceFilesSize = converterDefinition.getSourceFileDefinitions().size();
} else {
sourceFilesSize = 0;
}
}
public void setDefaultSourceFilePath(String sourceFilePath) {
if (sourceFilePath == null) {
throw new IllegalArgumentException(
"Parameter 'sourceFilePath' must not be null.");
}
for (int i = 0; i < sourceFiles.size(); i++) {
SourceFile sourceFile = sourceFiles.get(i);
sourceFile.setPath(sourceFilePath);
sourceFile.setOffset(0);
}
}
public int getSourceFilesSize() {
return sourceFilesSize;
}
public SourceFile getSourceFile(int sourceFileId) {
return sourceFiles.get(sourceFileId);
}
public void setImageFilePath(String value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.imageFilePath = value;
}
public String getImageFilePath() {
return imageFilePath;
}
public void setColumns(int value) {
this.columns = value;
}
public int getColumns() {
return columns;
}
public void setRows(int value) {
this.rows = value;
}
public int getRows() {
return rows;
}
/**
* Sets the spacing color.
*
* @param value
* The spacing color or <code>null</code> to set the default
* value.
*/
public void setSpacingColor(RGB value) {
if (value == null) {
value = Defaults.SPACING_COLOR;
}
this.spacingColor = value;
}
/**
* Gets the spacing color.
*
* @return The spacing color, not <code>null</code>.
*/
public RGB getSpacingColor() {
if (spacingColor == null) {
throw new IllegalStateException("Spacing color must not be null");
}
return spacingColor;
}
public void setSpacingWidth(int value) {
this.spacingWidth = value;
}
public int getSpacingWidth() {
return spacingWidth;
}
public void setPaletteType(PaletteType value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.paletteType = value;
}
public PaletteType getPaletteType() {
return paletteType;
}
public void setPalette(Palette value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.palette = value;
}
public void setPaletteManual() {
switch (palette) {
case TRUE_COLOR:
palette = Palette.TRUE_COLOR;
break;
case HIRES_1:
case HIRES_2:
case HIRES_MANUAL:
palette = Palette.HIRES_MANUAL;
break;
case MULTI_1:
case MULTI_2:
case MULTI_3:
case MULTI_4:
case MULTI_5:
case MULTI_6:
case MULTI_MANUAL:
palette = Palette.MULTI_MANUAL;
break;
case GTIA_GREY_1:
case GTIA_GREY_2:
case GTIA_GREY_MANUAL:
palette = Palette.GTIA_GREY_MANUAL;
break;
}
}
public Palette getPalette() {
return palette;
}
/**
* Sets the array of palette RGBs. Note that the values is kept as a reference.
*
* @param value The array of palette RGBs, may be empty, not <code>null</code>.
*/
public void setPaletteRGBs(RGB[] value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.paletteRGBs = value;
}
/**
* Gets the array of palette RGBs. Note that the returned values is a reference.
*
* @return The array of palette RGBs, may be empty, not <code>null</code>.
*/
public RGB[] getPaletteRGBs() {
return paletteRGBs;
}
protected final void copyTo(FilesConverterParameters target) {
if (target == null) {
throw new IllegalArgumentException(
"Parameter 'target' must not be null.");
}
super.copyTo(target);
target.sourceFiles.clear();
for (SourceFile sourceFile : sourceFiles) {
SourceFile targetSourceFile;
targetSourceFile = new SourceFile(sourceFile.getId());
targetSourceFile.setPath(sourceFile.getPath());
targetSourceFile.setOffset(sourceFile.getOffset());
target.sourceFiles.add(targetSourceFile);
}
target.setImageFilePath(imageFilePath);
target.setRows(rows);
target.setColumns(columns);
target.setSpacingColor(spacingColor);
target.setSpacingWidth(spacingWidth);
target.setPaletteType(paletteType);
target.setPalette(palette);
target.setPaletteRGBs(paletteRGBs);
}
protected final boolean equals(FilesConverterParameters target) {
if (target == null) {
throw new IllegalArgumentException(
"Parameter 'target' must not be null.");
}
boolean result;
result = super.equals(target);
result = result && target.sourceFiles.equals(sourceFiles);
result = result && target.getImageFilePath().equals(imageFilePath);
result = result && target.getRows() == rows;
result = result && target.getColumns() == columns;
result = result && target.getSpacingColor().equals(spacingColor);
result = result && target.getSpacingWidth() == spacingWidth;
result = result && target.getPaletteType().equals(paletteType);
result = result && target.getPalette().equals(palette);
result = result && Arrays.equals(target.getPaletteRGBs(), paletteRGBs);
return result;
}
@Override
protected final void serialize(GraphicsPropertiesSerializer serializer,
String key) {
if (serializer == null) {
throw new IllegalArgumentException(
"Parameter 'serializer' must not be null.");
}
if (key == null) {
throw new IllegalArgumentException(
"Parameter 'key' must not be null.");
}
super.serialize(serializer, key);
GraphicsPropertiesSerializer ownSerializer;
ownSerializer = new GraphicsPropertiesSerializer();
ownSerializer.writeInteger(Attributes.SOURCE_FILES, sourceFilesSize);
for (int i = 0; i < sourceFilesSize; i++) {
SourceFile sourceFile = sourceFiles.get(i);
GraphicsPropertiesSerializer innerSeralizer;
innerSeralizer = new GraphicsPropertiesSerializer();
innerSeralizer.writeString(Attributes.SOURCE_FILE_PATH,
sourceFile.getPath());
innerSeralizer.writeInteger(Attributes.SOURCE_FILE_OFFSET,
sourceFile.getOffset());
ownSerializer.writeProperties(Attributes.SOURCE_FILES + "." + i,
innerSeralizer);
}
ownSerializer.writeString(Attributes.IMAGE_FILE_PATH, imageFilePath);
ownSerializer.writeInteger(Attributes.COLUMNS, columns);
ownSerializer.writeInteger(Attributes.ROWS, rows);
ownSerializer.writeRGB(Attributes.SPACING_COLOR, spacingColor);
ownSerializer.writeInteger(Attributes.SPACING_WIDTH, spacingWidth);
ownSerializer.writeEnum(Attributes.PALETTE, palette);
ownSerializer.writeEnum(Attributes.PALETTE_TYPE, paletteType);
ownSerializer.writeRGBArray(Attributes.PALETTE_COLORS, paletteRGBs);
serializer.writeProperties(key, ownSerializer);
}
@Override
protected final void deserialize(GraphicsPropertiesSerializer serializer,
String key) {
if (serializer == null) {
throw new IllegalArgumentException(
"Parameter 'serializer' must not be null.");
}
if (key == null) {
throw new IllegalArgumentException();
}
super.deserialize(serializer, key);
GraphicsPropertiesSerializer ownSerializer;
ownSerializer = new GraphicsPropertiesSerializer();
serializer.readProperties(key, ownSerializer);
sourceFiles.clear();
for (int i = 0; i < ConverterRegistry.MAX_SOURCE_FILES; i++) {
SourceFile sourceFile = new SourceFile(i);
GraphicsPropertiesSerializer innerSerializer;
innerSerializer = new GraphicsPropertiesSerializer();
ownSerializer.readProperties(Attributes.SOURCE_FILES + "." + i,
innerSerializer);
sourceFile.setPath(innerSerializer.readString(
Attributes.SOURCE_FILE_PATH, Defaults.SOURCE_FILE_PATH));
sourceFile
.setOffset(innerSerializer.readInteger(
Attributes.SOURCE_FILE_OFFSET,
Defaults.SOURCE_FILE_OFFSET));
sourceFiles.add(sourceFile);
}
imageFilePath = ownSerializer.readString(Attributes.IMAGE_FILE_PATH,
Defaults.IMAGE_FILE_PATH);
columns = ownSerializer.readInteger(Attributes.COLUMNS,
Defaults.COLUMNS);
rows = ownSerializer.readInteger(Attributes.ROWS, Defaults.ROWS);
spacingColor = ownSerializer.readRGB(Attributes.SPACING_COLOR,
Defaults.SPACING_COLOR);
spacingWidth = ownSerializer.readInteger(Attributes.SPACING_WIDTH,
Defaults.SPACING_WIDTH);
palette = ownSerializer.readEnum(Attributes.PALETTE, Defaults.PALETTE,
Palette.class);
paletteType = ownSerializer.readEnum(Attributes.PALETTE_TYPE,
Defaults.PALETTE_TYPE, PaletteType.class);
paletteRGBs = ownSerializer.readRGBArray(Attributes.PALETTE_COLORS,
Defaults.PALETTE_COLORS);
}
}

View File

@ -0,0 +1,240 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TreeMap;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.base.common.NumberFactory;
/**
* Image color histogram container. Counts the number of occurrences of a pixel
* color value in an image data. Pixel color values may be greater than 256 in
* case of direct palettes.
*
* @author Peter Dell
*/
public final class ImageColorHistogram {
private PaletteData paletteData;
private int pixelCount;
private List<Integer> pixelColors;
private List<Integer> usedPixelColors;
private TreeMap<Integer, Integer> pixelColorCounts;
/**
* Created by {@link ImageConverterData}.
*/
ImageColorHistogram() {
pixelColors = Collections.emptyList();
usedPixelColors = Collections.emptyList();
pixelColorCounts = new TreeMap<Integer, Integer>();
}
/**
* Clears the histogram.
*/
final void clear() {
paletteData = null;
pixelCount = 0;
pixelColors = Collections.emptyList();
usedPixelColors = Collections.emptyList();
pixelColorCounts.clear();
}
/**
* Counts the number of occurrences of a pixel value in the image data.
*
* @param imageData
* The image data or <code>null</code>.
*/
final void analyze(ImageData imageData) {
clear();
if (imageData != null) {
pixelCount = imageData.height * imageData.width;
paletteData = imageData.palette;
if (paletteData.isDirect) {
pixelColors = Collections.emptyList();
} else {
RGB[] rgbs = paletteData.getRGBs();
int size = rgbs.length;
pixelColors = new ArrayList<Integer>(size);
for (int i = 0; i < size; i++) {
pixelColors.add(NumberFactory.getInteger(i));
}
pixelColors = Collections.unmodifiableList(pixelColors);
}
for (int y = 0; y < imageData.height; y++) {
for (int x = 0; x < imageData.width; x++) {
Integer pixelColor = NumberFactory.getInteger(imageData
.getPixel(x, y));
Integer pixelColorCount = pixelColorCounts.get(pixelColor);
if (pixelColorCount == null) {
pixelColorCount = NumberFactory.getInteger(1);
} else {
pixelColorCount = NumberFactory
.getInteger(pixelColorCount.intValue() + 1);
}
pixelColorCounts.put(pixelColor, pixelColorCount);
}
}
} else {
pixelColors = Collections.emptyList();
}
usedPixelColors = Collections.unmodifiableList(new ArrayList<Integer>(
pixelColorCounts.keySet()));
}
public boolean isDirectPalette() {
if (paletteData == null) {
return true;
}
return paletteData.isDirect;
}
/**
* Gets the number of bits used for representing pixels.
*
* @return The number of bits used for representing pixels or <code>0</code>
* if there is no image.
*/
public int getPaletteBits() {
if (paletteData == null) {
return 0;
}
if (paletteData.isDirect) {
return Integer.bitCount(paletteData.redMask)
+ Integer.bitCount(paletteData.greenMask)
+ Integer.bitCount(paletteData.blueMask);
}
int length = paletteData.getRGBs().length;
int result = 0;
while (length != 0) {
result++;
length = length >>> 1;
}
return result;
}
/**
* Gets the total number of pixels in the image data. It corresponds to the
* sum of count returned by {@link #getPixelColorCount(Integer)}.
*
* @return The total pixel color count.
*/
public int getPixelCount() {
return pixelCount;
}
/**
* Gets the list of all pixel colors in the palette if the palette is an
* indexed palette. If the palette is not indexed, the result is an empty
* list.
*
* @return The unmodifiable list of pixel colors, sorted by their pixel
* value, may be empty, not <code>null</code>.
*/
public List<Integer> getPalettePixelColors() {
return pixelColors;
}
/**
* Gets the list of used pixel colors in the image data, sorted by their
* pixel value. This method work the same way for direct and indexed
* palettes.
*
* @return The unmodifiable list of pixel colors, sorted by their pixel
* value, may be empty, not <code>null</code>.
*/
public List<Integer> getUsedPixelColors() {
return usedPixelColors;
}
/**
* Gets the number of occurrences of a pixel color value in the image data.
*
* @param pixelColor
* The pixel color, not <code>null</code>.
* @return The count or <code>0</code> in case the pixel color is not
* contained in the image.
*/
public int getPixelColorCount(Integer pixelColor) {
if (pixelColor == null) {
throw new IllegalArgumentException(
"Parameter 'pixelColor' must not be null.");
}
Integer count = pixelColorCounts.get(pixelColor);
if (count == null) {
return 0;
}
return count.intValue();
}
/**
* Gets the RGB value for a pixel color. This method work the same way for
* direct and indexed palettes.
*
* @param pixelColor
* The pixel color, not <code>null</code>.
* @return The RGB value for the pixel color, not <code>null</code>.
*/
public RGB getRGB(Integer pixelColor) {
if (pixelColor == null) {
throw new IllegalArgumentException(
"Parameter 'pixelColor' must not be null.");
}
RGB rgb;
if (paletteData != null) {
// Indexed palette images may contain pixel values without
// corresponding
int intValue = pixelColor.intValue();
if (paletteData.isDirect) {
rgb = paletteData.getRGB(intValue);
} else {
// In indexed palette images, the palette may be shorter than
// the actually used color.
RGB[] rgbs = paletteData.getRGBs();
if (intValue < rgbs.length) {
rgb = rgbs[intValue];
if (rgb == null) {
throw new IllegalStateException(
"Palette data has no RGB value at index "
+ intValue + ".");
}
} else {
rgb = new RGB(0, 0, 0);
}
}
} else {
rgb = new RGB(0, 0, 0);
}
return rgb;
}
}

View File

@ -0,0 +1,247 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.RGB;
import org.mozilla.javascript.NativeArray;
import com.wudsn.ide.gfx.GraphicsPlugin;
import com.wudsn.ide.gfx.model.ConverterMode;
public final class ImageConverterData extends ConverterCommonData {
private ImageConverterParameters parameters;
// Purely transient cache attributes.
private transient ConverterScriptData converterScriptData;
private transient ImageData targetImageData;
private transient List<byte[]> targetFilesBytes;
ImageConverterData(ConverterData converterData) {
super(converterData);
this.parameters = converterData.getParameters().getImageConverterParameters();
converterScriptData = new ConverterScriptData();
targetFilesBytes = new ArrayList<byte[]>(0);
}
public ImageConverterParameters getParameters() {
return parameters;
}
public Converter getConverter() {
ConverterRegistry converterRegistry;
Converter converter;
converterRegistry = GraphicsPlugin.getInstance().getConverterRegistry();
converter = converterRegistry.getConverter(parameters.getConverterId());
return converter;
}
@Override
public boolean isCreateConversionEnabled() {
return converterData.isValid() && converterData.getConverterMode() == ConverterMode.RAW_IMAGE;
}
@Override
public boolean isValid() {
return converterData.isValidImage();
}
public boolean isValidConversion() {
return converterData.isValidConversion();
}
@Override
public boolean isRefreshEnabled() {
return converterData.isValidImage();
}
public boolean isSaveFilesEnabled() {
if (converterData.isValidConversion()) {
for (byte[] bytes : targetFilesBytes) {
if (bytes != null) {
return true;
}
}
}
return false;
}
/**
* Clears the image data.
*/
@Override
public void clear() {
super.clear();
clearTargetFileBytes();
}
/**
* Gets the pixel color value for a given position. There must be an
* instance of image data set.
*
* @param x
* The x position, a non-negative integer.
* @param y
* The y position, a non-negative integer.
*
* @return The pixel color value.
*
* @throws NullPointerException
* if there is no image data at all.
*/
public int getPixel(int x, int y) {
try {
return imageData.getPixel(x, y);
} catch (IllegalArgumentException ex) {
throw new RuntimeException("Pixel (" + x + "," + y + ") is outside of the image.");
}
}
/**
* Gets the pixel RGB value for a given position. There must be an instance
* of image data set.
*
* @param x
* The x position, a non-negative integer.
* @param y
* The y position, a non-negative integer.
*
* @return The pixel color value.
*
* @throws NullPointerException
* if there is no image data at all.
*/
public int getPixelRGB(int x, int y) {
int result = getPixel(x, y);
if (!imageData.palette.isDirect) {
RGB rgb = imageData.palette.getRGB(result);
result = rgb.red << 16 | rgb.green << 8 | rgb.blue;
}
return result;
}
/**
* Sets the target image data, i.e. the image data after converting it to
* files and back.
*
* @param targetImageData
* The target image data or <code>null</code>.
*/
public void setTargetImageData(ImageData targetImageData) {
this.targetImageData = targetImageData;
}
/**
* Gets the target image data, i.e. the image data after converting is to
* files and back.
*
* @return The target image data or <code>null</code>.
*/
public ImageData getTargetImageData() {
return targetImageData;
}
/**
* Gets the container for the converter script.
*
* @return The container for the converter script, not <code>null</code>.
*/
public ConverterScriptData getConverterScriptData() {
return converterScriptData;
}
/**
* Clears all target files bytes.
*/
public void clearTargetFileBytes() {
targetFilesBytes.clear();
}
/**
* Sets the bytes for a target file from java script.
*
* @param targetFileId
* The target field id, a non-negative integer.
* @param scriptBytes
* The bytes, may be empty or <code>null</code>.
*/
public void setTargetFileObject(int targetFileId, NativeArray scriptBytes) {
byte[] bytes = null;
if (scriptBytes != null) {
int length = (int) scriptBytes.getLength();
bytes = new byte[length];
for (int i = 0; i < length; i++) {
Object o = scriptBytes.get(i, null);
if (o instanceof Double) {
bytes[i] = ((Double) o).byteValue();
} else if (o instanceof Integer) {
bytes[i] = ((Integer) o).byteValue();
}
}
}
setTargetFileBytes(targetFileId, bytes);
}
/**
* Sets the bytes for a target file.
*
* @param targetFileId
* The target field id, a non-negative integer.
* @param bytes
* The bytes, may be empty or <code>null</code>.
*/
public void setTargetFileBytes(int targetFileId, byte[] bytes) {
if (targetFileId < 0) {
throw new IllegalArgumentException("Parameter 'targetFileId' must not be negative. Specified value is "
+ targetFileId + ".");
}
while (targetFilesBytes.size() <= targetFileId) {
targetFilesBytes.add(null);
}
targetFilesBytes.set(targetFileId, bytes);
}
/**
* Gets the bytes for a target file.
*
* @param targetFileId
* The target field id, a non-negative integer.
* @return The bytes, may be empty or <code>null</code>.
*/
public byte[] getTargetFileBytes(int targetFileId) {
if (targetFileId < 0) {
throw new IllegalArgumentException("Parameter 'targetFileId' must not be negative. Specified value is "
+ targetFileId + ".");
}
byte[] bytes;
if (targetFileId < targetFilesBytes.size()) {
bytes = targetFilesBytes.get(targetFileId);
} else {
bytes = null;
}
return bytes;
}
}

View File

@ -0,0 +1,372 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.util.ArrayList;
import java.util.List;
import com.wudsn.ide.gfx.GraphicsPlugin;
import com.wudsn.ide.gfx.model.ConverterDirection;
import com.wudsn.ide.gfx.model.GraphicsPropertiesSerializer;
public final class ImageConverterParameters extends ConverterCommonParameters {
public static final class Attributes {
/**
* Creation is private.
*/
private Attributes() {
}
public static final String IMAGE_FILE_PATH = "imageFilePath";
public static final String TARGET_FILES = "targetFiles";
public static final String TARGET_FILE_PATH = "path";
public static final String USE_DEFAULT_SCRIPT = "useDefaultScript";
public static final String SCRIPT = "script";
}
private static final class Defaults {
/**
* Creation is private.
*/
private Defaults() {
}
public static final String IMAGE_FILE_PATH = "";
public static final String TARGET_FILE_PATH = "";
public static final boolean USE_DEFAULT_SCRIPT = true;
public static final String SCRIPT = "";
}
public static final class MessageIds {
/**
* Creation is private.
*/
private MessageIds() {
}
public static final int IMAGE_FILE_PATH = 2010;
public static final int TARGET_FILE_PATH = 2020;
public static final int TARGET_FILE_OFFSET = 2030;
public static final int USE_DEFAULT_SCRIPT = 2040;
public static final int SCRIPT = 2041;
}
public static final class TargetFile {
private int id;
private String path;
private int offset;
public TargetFile(int id) {
this.id = id;
path = Defaults.TARGET_FILE_PATH;
}
public int getId() {
return id;
}
public int getPathMessageId() {
return MessageIds.TARGET_FILE_PATH + id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
if (path == null) {
throw new IllegalArgumentException(
"Parameter 'path' must not be null.");
}
this.path = path;
}
public int getOffsetMessageId() {
return MessageIds.TARGET_FILE_OFFSET + id;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
throw new IllegalArgumentException(
"Parameter 'obj' must not be null.");
}
TargetFile other = (TargetFile) obj;
return other.id == this.id && other.path.equals(this.path)
&& other.offset == this.offset;
}
@Override
public int hashCode() {
return id + 7 * path.hashCode() + 17 * offset;
}
}
private String imageFilePath;
private int targetFilesSize;
private List<TargetFile> targetFiles;
private boolean useDefaultScript;
private String script;
ImageConverterParameters() {
int size = ConverterRegistry.MAX_SOURCE_FILES;
this.targetFiles = new ArrayList<TargetFile>(size);
for (int i = 0; i < size; i++) {
this.targetFiles.add(new TargetFile(i));
}
setDefaults();
}
@Override
public void setDefaults() {
super.setDefaults();
imageFilePath = Defaults.IMAGE_FILE_PATH;
for (TargetFile targetFile : targetFiles) {
targetFile.setPath(Defaults.TARGET_FILE_PATH);
}
useDefaultScript = Defaults.USE_DEFAULT_SCRIPT;
script = Defaults.SCRIPT;
}
@Override
public void setConverterId(String value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
if (!value.equals(this.converterId))
this.converterId = value;
ConverterDefinition converterDefinition;
converterDefinition = GraphicsPlugin.getInstance()
.getConverterRegistry()
.getDefinition(converterId, ConverterDirection.IMAGE_TO_FILES);
if (converterDefinition != null) {
targetFilesSize = targetFiles.size();
} else {
targetFilesSize = 0;
}
}
public void setDefaultTargetFilePath(String targetFilePath) {
if (targetFilePath == null) {
throw new IllegalArgumentException(
"Parameter 'targetFilePath' must not be null.");
}
for (int i = 0; i < targetFiles.size(); i++) {
TargetFile targetFile = targetFiles.get(i);
targetFile.setPath(targetFilePath);
targetFile.setOffset(0);
}
}
public void setImageFilePath(String value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.imageFilePath = value;
}
public String getImageFilePath() {
return imageFilePath;
}
public int getTargetFilesSize() {
return targetFilesSize;
}
public TargetFile getTargetFile(int targetFileId) {
return targetFiles.get(targetFileId);
}
/**
* Sets the indicator to use the default script
*
* @param value
* <code>true</code> to use the default script,
* <code>false</code> to use the saved script.
*/
public void setUseDefaultScript(boolean value) {
this.useDefaultScript = value;
}
/**
* Gets the indicator to use the default script
*
* @return <code>true</code> to use the default script, <code>false</code>
* to use the saved script.
*/
public boolean isUseDefaultScript() {
return useDefaultScript;
}
/**
* Gets the script for the conversion logic.
*
* @param value
* The script, may be empty, not <code>null</code>.
*/
public void setScript(String value) {
if (value == null) {
throw new IllegalArgumentException(
"Parameter 'value' must not be null.");
}
this.script = value;
}
/**
* Gets the script for the conversion logic.
*
* @return The script, may be empty, not <code>null</code>.
*/
public String getScript() {
if (script == null) {
throw new IllegalStateException("Field 'script' must not be null.");
}
return script;
}
protected final void copyTo(ImageConverterParameters target) {
if (target == null) {
throw new IllegalArgumentException(
"Parameter 'target' must not be null.");
}
super.copyTo(target);
target.setImageFilePath(imageFilePath);
target.targetFiles.clear();
for (TargetFile targetFile : targetFiles) {
TargetFile targetTargetFile;
targetTargetFile = new TargetFile(targetFile.getId());
targetTargetFile.setPath(targetFile.getPath());
targetTargetFile.setOffset(targetFile.getOffset());
target.targetFiles.add(targetTargetFile);
}
target.setUseDefaultScript(useDefaultScript);
target.setScript(script);
}
protected final boolean equals(ImageConverterParameters target) {
if (target == null) {
throw new IllegalArgumentException(
"Parameter 'target' must not be null.");
}
boolean result;
result = super.equals(target);
result = result && target.getImageFilePath().equals(imageFilePath);
result = result && target.targetFiles.equals(targetFiles);
result = result && target.isUseDefaultScript() == useDefaultScript;
result = result && target.getScript().equals(script);
return result;
}
@Override
protected final void serialize(GraphicsPropertiesSerializer serializer,
String key) {
if (serializer == null) {
throw new IllegalArgumentException(
"Parameter 'serializer' must not be null.");
}
if (key == null) {
throw new IllegalArgumentException(
"Parameter 'key' must not be null.");
}
super.serialize(serializer, key);
GraphicsPropertiesSerializer ownSerializer;
ownSerializer = new GraphicsPropertiesSerializer();
ownSerializer.writeString(Attributes.IMAGE_FILE_PATH, imageFilePath);
ownSerializer.writeInteger(Attributes.TARGET_FILES, targetFilesSize);
for (int i = 0; i < targetFilesSize; i++) {
TargetFile targetFile = targetFiles.get(i);
GraphicsPropertiesSerializer innerSeralizer;
innerSeralizer = new GraphicsPropertiesSerializer();
innerSeralizer.writeString(Attributes.TARGET_FILE_PATH,
targetFile.getPath());
ownSerializer.writeProperties(Attributes.TARGET_FILES + "." + i,
innerSeralizer);
}
ownSerializer.writeBoolean(Attributes.USE_DEFAULT_SCRIPT, useDefaultScript);
ownSerializer.writeString(Attributes.SCRIPT, script);
serializer.writeProperties(key, ownSerializer);
}
@Override
protected final void deserialize(GraphicsPropertiesSerializer serializer,
String key) {
if (serializer == null) {
throw new IllegalArgumentException(
"Parameter 'serializer' must not be null.");
}
if (key == null) {
throw new IllegalArgumentException();
}
super.deserialize(serializer, key);
GraphicsPropertiesSerializer ownSerializer;
ownSerializer = new GraphicsPropertiesSerializer();
serializer.readProperties(key, ownSerializer);
imageFilePath = ownSerializer.readString(Attributes.IMAGE_FILE_PATH,
Defaults.IMAGE_FILE_PATH);
imageFilePath = ownSerializer.readString(Attributes.IMAGE_FILE_PATH,
Defaults.IMAGE_FILE_PATH);
targetFiles.clear();
for (int i = 0; i < ConverterRegistry.MAX_TARGET_FILES; i++) {
TargetFile targetFile = new TargetFile(i);
GraphicsPropertiesSerializer innerSerializer;
innerSerializer = new GraphicsPropertiesSerializer();
ownSerializer.readProperties(Attributes.TARGET_FILES + "." + i,
innerSerializer);
targetFile.setPath(innerSerializer.readString(
Attributes.TARGET_FILE_PATH, Defaults.TARGET_FILE_PATH));
targetFiles.add(targetFile);
}
useDefaultScript = ownSerializer.readBoolean(
Attributes.USE_DEFAULT_SCRIPT, Defaults.USE_DEFAULT_SCRIPT);
script = ownSerializer.readString(Attributes.SCRIPT, Defaults.SCRIPT);
}
}

View File

@ -0,0 +1,70 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
/**
* Square block of character which shall be inverse
*
* @author Peter Dell
*/
public final class InverseBlock {
private int column1;
private int column2;
private int row1;
private int row2;
private Integer inverseColor;
private boolean inverseIfConflict;
InverseBlock(int column1, int column2, int row1, int row2,
Integer inverseColor, boolean inverseIfConflict) {
this.column1 = column1;
this.column2 = column2;
this.row1 = row1;
this.row2 = row2;
this.inverseColor = inverseColor;
this.inverseIfConflict = inverseIfConflict;
}
public int getColumn1() {
return column1;
}
public int getColumn2() {
return column2;
}
public int getRow1() {
return row1;
}
public int getRow2() {
return row2;
}
public Integer getInverseColor() {
return inverseColor;
}
public boolean isInverseIfConflict() {
return inverseIfConflict;
}
}

View File

@ -0,0 +1,88 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.util.ArrayList;
import java.util.List;
/**
* List of square blocks of character which shall be inverse
*
* @author Peter Dell
*/
public final class InverseBlockList {
private List<InverseBlock> inverseBlocks;
/**
* Creates an empty inverse block list.
*/
public InverseBlockList() {
inverseBlocks = new ArrayList<InverseBlock>();
}
/**
* Adds a new inverse block to the list.
*
* @param column1
* Start column, a non-negative integer
* @param column2
* End column, a non-negative integer
* @param row1
* Start row, a non-negative integer
* @param row2
* End row, a non-negative integer
* @param inverseColor
* The pixel color value which shall be used as inverse color
* @param inverseIfConflict
* <code>true</code> if the inverse color shall also be used in
* case of conflict
*/
public void add(int column1, int column2, int row1, int row2,
Integer inverseColor, boolean inverseIfConflict) {
inverseBlocks.add(new InverseBlock(column1, column2, row1, row2,
inverseColor, inverseIfConflict));
}
/**
* Get the inverse block at The sequence in which the blocks were added
* determines, the sequence in which the method checks for matches.
*
* @param column
* The column, a non-negative integer.
* @param row
* The column, a non-negative integer.
* @return The first matching inverse block, or <code>null</code> if no
* inverse block matches.
*/
public InverseBlock getInverseBlock(int column, int row) {
for (InverseBlock inverseBlock : inverseBlocks) {
if (inverseBlock.getColumn1() <= column
&& column <= inverseBlock.getColumn2()
&& inverseBlock.getRow1() <= row
&& row <= inverseBlock.getRow2()) {
return inverseBlock;
}
}
return null;
}
}

View File

@ -0,0 +1,177 @@
package com.wudsn.ide.gfx.converter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.base.common.NumberFactory;
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter
* Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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
* WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Palette mapper for mapping palette indices to RGB and back. The palette data
* is stored in files in the folder for the sub-package "/palettes", relative to
* the location if the palette mapper implementation class. The file content is
* loaded from the class path using the class loader.
*
*
* @since 1.6.4
*/
public abstract class PaletteMapper {
private int palette_size;
private int[] palette_r;
private int[] palette_g;
private int[] palette_b;
private Map<Integer, Integer> map;
protected PaletteMapper(int palette_size) {
if (palette_size < 1) {
throw new IllegalArgumentException("Parameter 'palette_size' must be positive. Specified value is "
+ palette_size + ".");
}
this.palette_size = palette_size;
map = new HashMap<Integer, Integer>();
palette_r = new int[palette_size];
palette_g = new int[palette_size];
palette_b = new int[palette_size];
}
public final void loadPalette(String fileName) {
if (fileName == null) {
throw new IllegalArgumentException("Parameter 'fileName' must not be null.");
}
InputStream inputStream;
Class<? extends PaletteMapper> clazz = getClass();
inputStream = clazz.getClassLoader().getResourceAsStream(
clazz.getPackage().getName().replace('.', '/') + "/palettes/" + fileName);
if (inputStream == null) {
try {
inputStream = new FileInputStream(fileName);
} catch (FileNotFoundException ex) {
throw new RuntimeException("File '" + fileName + "' not found or not readable", ex);
}
}
byte[] buffer = new byte[palette_size * 3];
int count;
do {
try {
count = inputStream.read(buffer);
} catch (IOException ex) {
throw new RuntimeException("Cannot read palette '" + fileName + "'", ex);
}
if (count > 0) {
int j = 0;
for (int i = 0; i < count; i = i + 3, j++) {
palette_r[j] = buffer[i] & 0xff;
palette_g[j] = buffer[i + 1] & 0xff;
palette_b[j] = buffer[i + 2] & 0xff;
}
}
} while (count > -1);
map.clear();
}
/**
* Gets the index of an RGB value in the palette.
*
* @param rgb
* The 24-bit RGB value
* @return The palette index, or <code>-1</code> is there is not
* corresponding palette index.
*/
public final int getPaletteIndex(int rgb) {
return getPaletteIndex(rgb >>> 16 & 0xff, rgb >>> 8 & 0xff, rgb & 0xff);
}
/**
* Gets the index of an RGB value in the palette.
*
* @param r
* The 8-bit red value
* @param g
* The 8-bit green value
* @param b
* The 8-bit blue value
* @return The palette index, or <code>-1</code> is there is not
* corresponding palette index.
*/
public final int getPaletteIndex(int r, int g, int b) {
int color = r << 16 | g << 8 | b;
Integer colorKey = NumberFactory.getInteger(color);
Integer colorValue = map.get(colorKey);
if (colorValue == null) {
int diff = 0x7fffffff;
int n = 0;
for (int m = 0; m < 256; m++) {
int e = (palette_r[m] - r);
int d = e * e;
e = (palette_g[m] - g);
d += e * e;
e = (palette_b[m] - b);
d += e * e;
if (d < diff) {
diff = d;
n = m;
}
}
colorValue = new Integer(n);
map.put(colorKey, colorValue);
}
return colorValue.intValue();
}
/**
* Gets an Atari color with a given color code as RGB value.
*
* @param paletteIndex
* The palette index, a non-negative integer.
* @return The RGB value, not <code>null</code>.
*/
public final RGB getRGB(int paletteIndex) {
RGB result;
result = new RGB(palette_r[paletteIndex], palette_g[paletteIndex], palette_b[paletteIndex]);
return result;
}
/**
* Gets an Atari color with a given color code as RGB int value.
*
* @param paletteIndex
* The palette index, a non-negative integer.
* @return The RGB color, not <code>null</code>.
*/
public final int getRGBColor(int paletteIndex) {
int result = palette_r[paletteIndex] << 16 | palette_g[paletteIndex] << 8 | palette_b[paletteIndex];
return result;
}
}

View File

@ -0,0 +1,261 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import com.wudsn.ide.base.common.NumberFactory;
public final class Tile {
private TileSet tileSet;
private int column;
private int row;
private int xOffset;
private int yOffset;
private Map<Integer, Integer> pixelColorCounts;
private List<Map<Integer, Integer>> linePixelColorCounts;
private boolean inverseConflict;
public Tile(TileSet tileSet, int column, int row) {
if (tileSet == null) {
throw new IllegalArgumentException(
"Parameter 'tileSet' must not be null.");
}
if (column < 0) {
throw new IllegalArgumentException(
"Parameter 'column' must not be negative. Specified value is "
+ column + ".");
}
if (row < 0) {
throw new IllegalArgumentException(
"Parameter 'row' must not be negative. Specified value is "
+ row + ".");
}
this.tileSet = tileSet;
this.column = column;
this.row = row;
xOffset = column * tileSet.getPixelsPerColumn();
yOffset = row * tileSet.getPixelsPerRow();
pixelColorCounts = new TreeMap<Integer, Integer>();
linePixelColorCounts = new ArrayList<Map<Integer, Integer>>(tileSet
.getPixelsPerRow());
for (int y = 0; y < tileSet.getPixelsPerRow(); y++) {
linePixelColorCounts.add(new TreeMap<Integer, Integer>());
for (int x = 0; x < tileSet.getPixelsPerColumn(); x++) {
Integer pixelColor = getPixelColor(x, y);
increment(pixelColorCounts, pixelColor);
increment(linePixelColorCounts.get(y), pixelColor);
}
}
}
private void increment(Map<Integer, Integer> pixelColorCounts,
Integer pixelColorKey) {
if (pixelColorCounts == null) {
throw new IllegalArgumentException(
"Parameter 'pixelColorCounts' must not be null.");
}
if (pixelColorKey == null) {
throw new IllegalArgumentException(
"Parameter 'pixelColorKey' must not be null.");
}
Integer pixelColorCount = pixelColorCounts.get(pixelColorKey);
if (pixelColorCount == null) {
pixelColorCount = NumberFactory.getInteger(1);
} else {
pixelColorCount = NumberFactory.getInteger(pixelColorCount
.intValue() + 1);
}
pixelColorCounts.put(pixelColorKey, pixelColorCount);
}
public int getColumn() {
return column;
}
public int getRow() {
return row;
}
/**
* Gets the pixel color of a pixel in the tile.
*
* @param x
* The relative x position in the tile, a non-negative integer.
* @param y
* The relative x position in the tile, a non-negative integer.
* @return The pixel color, not <code>null</code>.
*/
public Integer getPixelColor(int x, int y) {
try {
return NumberFactory.getInteger(tileSet.getImageData().getPixel(
xOffset + x, yOffset + y));
} catch (IllegalArgumentException ex) {
// throw new IllegalArgumentException("Cannot access pixel at "
// + xOffset + "+" + x + ", " + yOffset + "+" + y + ".", ex);
return NumberFactory.getInteger(0);
}
}
public boolean hasPixelColor(Integer pixelColor) {
if (pixelColor == null) {
throw new IllegalArgumentException(
"Parameter 'pixelColor' must not be null.");
}
return getPixelColorCount(pixelColor) > 0;
}
public int getPixelColorCount(Integer pixelColor) {
if (pixelColor == null) {
throw new IllegalArgumentException(
"Parameter 'pixelColor' must not be null.");
}
Integer pixelColorCount = pixelColorCounts.get(pixelColor);
if (pixelColorCount == null) {
return 0;
}
return pixelColorCount.intValue();
}
/**
* Counts the map of distinct colors used and their count in the tile.
*
* @param ignoredPixelColors
* The array of colors to be ignored during counting or
* <code>null</code>.
* @return The map of distinct colors used and their count, not
* <code>null</code>.
*/
public Map<Integer, Integer> getDistinctPixelColorCounts(
List<Integer> ignoredPixelColors) {
if (ignoredPixelColors == null) {
throw new IllegalArgumentException(
"Parameter 'ignoredPixelColors' must not be null.");
}
Map<Integer, Integer> pixelColorCounts;
pixelColorCounts = new TreeMap<Integer, Integer>();
for (int y = 0; y < tileSet.getPixelsPerRow(); y++) {
for (int x = 0; x < tileSet.getPixelsPerColumn(); x++) {
Integer pixelColor = getPixelColor(x, y);
boolean ignore = false;
if (ignoredPixelColors != null
&& ignoredPixelColors.contains(pixelColor)) {
ignore = true;
}
if (!ignore) {
increment(pixelColorCounts, pixelColor);
}
}
}
return pixelColorCounts;
}
public static Integer getMajorColor(Map<Integer, Integer> pixelColorCounts,
List<Integer> ignoredPixelColors) {
if (pixelColorCounts == null) {
throw new IllegalArgumentException(
"Parameter 'pixelColorCounts' must not be null.");
}
if (pixelColorCounts.isEmpty()) {
throw new IllegalArgumentException(
"Parameter 'pixelColorCounts' must not be empty.");
}
Integer majorColor;
int majorColorCount;
majorColor = null;
majorColorCount = -1;
for (Map.Entry<Integer, Integer> entry : pixelColorCounts.entrySet()) {
if (ignoredPixelColors == null
|| !ignoredPixelColors.contains(entry.getKey())) {
if (entry.getValue().intValue() > majorColorCount) {
majorColor = entry.getKey();
}
}
}
return majorColor;
}
public int getLinePixelColorCount(int y, int pixelColor) {
Map<Integer, Integer> pixelColorCounts = linePixelColorCounts.get(y);
Integer pixelColorCount = pixelColorCounts.get(NumberFactory
.getInteger(pixelColor));
if (pixelColorCount == null) {
return 0;
}
return pixelColorCount.intValue();
}
/**
* Counts the map of distinct colors used and their count in a specific line
* of the tile.
*
* @param y
* The line of the tile, a non-negative integer.
* @param ignoredPixelColors
* The list of colors to be ignored during counting or
* <code>null</code>.
* @return The map of distinct colors used and their count, not
* <code>null</code>.
*/
public Map<Integer, Integer> getDistinctLinePixelColorCounts(int y,
List<Integer> ignoredPixelColors) {
if (y < 0) {
throw new IllegalArgumentException(
"Parameter 'y' must not be negative, specified value is "
+ y + ".");
}
Map<Integer, Integer> pixelColorCounts;
pixelColorCounts = new TreeMap<Integer, Integer>();
for (int x = 0; x < tileSet.getPixelsPerColumn(); x++) {
Integer pixelColor = getPixelColor(x, y);
boolean ignore = false;
if (ignoredPixelColors != null
&& ignoredPixelColors.contains(pixelColor)) {
ignore = true;
}
if (!ignore) {
increment(pixelColorCounts, pixelColor);
}
}
return pixelColorCounts;
}
public boolean isInverseConflict() {
return inverseConflict;
}
public void setInverseConflict(boolean inverseConflict) {
this.inverseConflict = inverseConflict;
}
}

View File

@ -0,0 +1,240 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter;
import org.eclipse.swt.graphics.ImageData;
/**
* An image data divided into a rectangle of tiles.
*
* @author Peter Dell
*
*/
public final class TileSet {
private ImageData imageData;
private int pixelsPerColumn;
private int pixelsPerRow;
private int columns;
private int rows;
private int paletteSize;
private Tile[][] tiles;
/**
* Creates a new tile set.
*
* @param imageData
* The source image data, not <code>null</code>.
* @param pixelsPerColumn
* The number of pixels per column, a positive integer.
* @param pixelsPerRow
* The number of pixels per row, a positive integer.
*/
public TileSet(ImageData imageData, int pixelsPerColumn, int pixelsPerRow) {
if (imageData == null) {
throw new IllegalArgumentException(
"Parameter 'imageData' must not be null.");
}
if (pixelsPerColumn < 1) {
throw new IllegalArgumentException(
"Parameter 'pixelsPerColumn' must be poitive. Specified value is "
+ pixelsPerColumn + ".");
}
if (pixelsPerRow < 1) {
throw new IllegalArgumentException(
"Parameter 'pixelsPerRow' must be poitive. Specified value is "
+ pixelsPerRow + ".");
}
this.imageData = imageData;
this.pixelsPerColumn = pixelsPerColumn;
this.pixelsPerRow = pixelsPerRow;
// Round-up columns and rows
columns = (imageData.width + pixelsPerColumn - 1) / pixelsPerColumn;
rows = (imageData.height + pixelsPerRow - 1) / pixelsPerRow;
// Create the tiles
tiles = new Tile[rows][];
for (int r = 0; r < rows; r++) {
tiles[r] = new Tile[columns];
for (int c = 0; c < columns; c++) {
Tile tile = new Tile(this, c, r);
tiles[r][c] = tile;
}
}
}
/**
* Gets the source image data.
*
* @return The source image data, not <code>null</code>.
*/
public ImageData getImageData() {
return imageData;
}
/**
* Gets the number of columns.
*
* @return The number of columns, a positive integer.
*/
public int getColumns() {
return columns;
}
/**
* Gets the number of rows.
*
* @return The number of rows, a positive integer.
*/
public int getRows() {
return rows;
}
/**
* Gets the number of pixels per column.
*
* @return The number of pixels per column, a positive integer.
*/
public int getPixelsPerColumn() {
return pixelsPerColumn;
}
/**
* Gets the number of pixels per row.
*
* @return The number of of pixels per row, a positive integer.
*/
public int getPixelsPerRow() {
return pixelsPerRow;
}
/**
* Gets the size of the palette.
*
* @return The size of the palette, a positive integer.
*/
public int getPaletteSize() {
return paletteSize;
}
/**
* Gets the tile a a given location.
*
* @param column
* The column, a non-negative integer
* @param row
* The row, a non-negative integer
* @return The tile, not <code>null</code>.
*/
public Tile getTile(int column, int row) {
if (column < 0) {
throw new IllegalArgumentException(
"Parameter 'column' must not be negative. Specified value is "
+ column + ".");
}
if (row < 0) {
throw new IllegalArgumentException(
"Parameter 'row' must not be negative. Specified value is "
+ row + ".");
}
return tiles[row][column];
}
/**
* Create an image data instance large enough to hold the tiled source
* image.
*
* @return The tile image data, not <code>null</code>.
*/
public ImageData createTiledImageData() {
int width = columns * (pixelsPerColumn + 1) + 1;
int height = rows * (pixelsPerRow + 1) + 1;
ImageData tiledImageData = new ImageData(width, height,
imageData.depth, imageData.palette);
return tiledImageData;
}
/**
* Draws bounding rectangles around the tiles of the target image data.
*
* @param targetImageData
* The target image data, not <code>null</code>.
* @param gridColor
* The pixel color for coloring the tile grid.
* @param inverseConflictColor
* The pixel color for coloring conflict tiles in the tile grid.
*/
public void drawTileBoundaries(ImageData targetImageData,
Integer gridColor, Integer inverseConflictColor) {
if (targetImageData == null) {
throw new IllegalArgumentException(
"Parameter 'targetImageData' must not be null.");
}
if (gridColor == null) {
throw new IllegalArgumentException(
"Parameter 'gridColor' must not be null.");
}
if (inverseConflictColor == null) {
throw new IllegalArgumentException(
"Parameter 'inverseConflictColor' must not be null.");
}
for (int r = 0; r < rows + 1; r++) {
int ty = r * (pixelsPerRow + 1);
for (int x = 0; x < targetImageData.width; x++) {
targetImageData.setPixel(x, ty, gridColor.intValue());
}
}
for (int c = 0; c < columns + 1; c++) {
int tx = c * (pixelsPerColumn + 1);
for (int y = 0; y < targetImageData.height; y++) {
targetImageData.setPixel(tx, y, gridColor.intValue());
}
}
for (int r = 0; r < rows; r++) {
int ty = r * (pixelsPerRow + 1);
for (int c = 0; c < columns; c++) {
int tx = c * (pixelsPerColumn + 1);
Tile tile = getTile(c, r);
if (tile.isInverseConflict()) {
for (int x = 0; x < pixelsPerColumn + 1; x++) {
targetImageData.setPixel(tx + x, ty,
inverseConflictColor.intValue());
targetImageData.setPixel(tx + x, ty + pixelsPerRow + 1,
inverseConflictColor.intValue());
}
for (int y = 0; y < pixelsPerRow + 1; y++) {
targetImageData.setPixel(tx, ty + y,
inverseConflictColor.intValue());
targetImageData.setPixel(tx + pixelsPerColumn + 1, ty
+ y, inverseConflictColor.intValue());
}
}
}
}
}
}

View File

@ -0,0 +1,119 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.apple2;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.FilesConverterParameters.SourceFile;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.PaletteType;
import com.wudsn.ide.gfx.model.PaletteUtility;
public class HiresGraphicsConverter extends LinearBitMapConverter {
static final int CELL_HEIGHT = 8;
static final int CELL_WIDTH = 7;
public HiresGraphicsConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 8184; // $1ff8
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
int columns = 40;
int rows = 24;
RGB[] paletteColors;
paletteColors = PaletteUtility.getPaletteColors(
PaletteType.ATARI_DEFAULT, Palette.HIRES_1, null);
setImageSizeAndPalette(data, columns, rows, Palette.HIRES_1,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
data.setImageDataWidth(data.getParameters().getColumns() * CELL_WIDTH);
data.setImageDataHeight(data.getParameters().getRows() * CELL_HEIGHT);
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
byte[] bytes = data.getSourceFileBytes(BIT_MAP_FILE);
if (bytes == null) {
return false;
}
SourceFile sourceFile = data.getParameters()
.getSourceFile(BIT_MAP_FILE);
int offset = sourceFile.getOffset();
for (int y1 = 0; y1 < data.getParameters().getRows() * CELL_HEIGHT; y1++) {
int y = y1;
int page = y & 0x7;
int block = ((y >> 3) & 0x7);
int leaf = y >> 6;
int yindex = offset + (page * 1024) + (block * 128) + (leaf * 40);
int x = 0;
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int xindex = yindex + x1;
if (xindex < bytes.length) {
int b = bytes[xindex];
for (int i = 0; i < CELL_WIDTH; i++) {
if ((b & (1 << i)) != 0) {
data.setPalettePixel(x, y1, 1);
}
x++;
}
}
}
}
return true;
}
}

View File

@ -0,0 +1,32 @@
function convertToFileData(data) {
var bytes = [];
var offset = 0;
var page = 0;
var block = 0;
var leaf = 0;
if ( data.getImageDataWidth() !=280
|| data.getImageDataHeight()!=192 ){
return;
}
for (var y = 0; y < data.getImageDataHeight(); y++) {
page = y & 0x7;
block = ((y >> 3) & 0x7);
leaf = y >> 6;
offset = (page*1024) + (block*128) + (leaf*40);
for (var x = 0; x < data.getImageDataWidth(); x = x + 7) {
var b = 0;
for (var i = 0; i < 7; i++) {
var color;
color = data.getPixel(x + i, y);
if (color != 0) {
b = b | 1 << i;
}
}
bytes[offset++] = b;
}
}
data.setTargetFileObject(0, bytes);
}

View File

@ -0,0 +1,73 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari2600;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.generic.BitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
public class AsymetricalPlayfieldConverter extends BitMapConverter {
public AsymetricalPlayfieldConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return false;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
int columns = 5;
int rows = (bytes.length + columns - 1) / columns;
setImageSizeAndPalette(data, columns, rows, Palette.HIRES_1, null);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns());
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
return false;
}
}

View File

@ -0,0 +1,40 @@
function convertToFileData(data) {
var lineHeight = 5; // Height of a single text line
var lineSpacing = 1; // Space between two text lines
var lineFullHeight = lineHeight + lineSpacing; // Full height of a text line
var lines = java.lang.Math.floor((data.getImageDataHeight() + lineHeight) / lineFullHeight); // Number of text lines
var scanLines = lines * lineHeight;
var columnOffsets= [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5];
var columnBits = [0x10,0x20,0x40,0x80,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x10,0x20,0x40,0x80,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80];
var bytes = [];
var offset = 0;
for (var l = 0; l < lines; l = l + 1) {
var y = l * lineFullHeight;
for (var m = 0; m < lineHeight; m++) {
var b = [0,0,0,0,0,0];
for (var x = 0; x < data.getImageDataWidth() && x < 40; x = x + 1) {
var color;
if (y+m < data.getImageDataHeight()){
color = data.getPixel(x, y + m);
} else {
color = 0;
}
if (color != 0) {
var o = columnOffsets[x];
b[o] = b[o] | columnBits[x];
}
}
bytes[offset+scanLines*0] = b[0];
bytes[offset+scanLines*1] = b[1];
bytes[offset+scanLines*2] = b[2];
bytes[offset+scanLines*3] = b[3];
bytes[offset+scanLines*4] = b[4];
bytes[offset+scanLines*5] = b[5];
offset =offset + 1;
}
}
data.setTargetFileObject(0, bytes);
}

View File

@ -0,0 +1,41 @@
package com.wudsn.ide.gfx.converter.atari8bit;
import com.wudsn.ide.gfx.converter.PaletteMapper;
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter
* Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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
* WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Palette mapper for mapping Atari color values to RGB and back.
*
* @since 1.6.4
*/
public final class Atari8BitPaletteMapper extends PaletteMapper {
public Atari8BitPaletteMapper() {
super(256);
// loadPalette("default.act");
loadPalette("laoo.act");
// loadPalette("real.act");
}
}

View File

@ -0,0 +1,233 @@
package com.wudsn.ide.gfx.converter.atari8bit;
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter
* Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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
* WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Based on the Atari RGB converter by Mark Keates / Wrathchild. See <a
* href=http://www.atariage.com/forums/topic/137075-rgb-to-atari-colors>http
* ://www.atariage.com/forums/topic/137075-rgb-to-atari-colors</a>.<br>
* See <a
* href=http://de.wikipedia.org/wiki/Lab-Farbraum>http://de.wikipedia.org/
* wiki/Lab-Farbraum</a>.<br>
*
* @author Mark Keates
* @author Peter Dell
*
* @since 1.6.0
*/
public class Atari8BitPaletteUtility {
/**
* TODO Make Atari8BitPaletteUtility real tool/view
*/
static int real_pal[] = { 0x323132, 0x3f3e3f, 0x4d4c4d, 0x5b5b5b, 0x6a696a,
0x797879, 0x888788, 0x979797, 0xa1a0a1, 0xafafaf, 0xbebebe,
0xcecdce, 0xdbdbdb, 0xebeaeb, 0xfafafa, 0xffffff, 0x612e00,
0x6c3b00, 0x7a4a00, 0x885800, 0x94670c, 0xa5761b, 0xb2842a,
0xc1943a, 0xca9d43, 0xdaad53, 0xe8bb62, 0xf8cb72, 0xffd87f,
0xffe88f, 0xfff79f, 0xffffae, 0x6c2400, 0x773000, 0x844003,
0x924e11, 0x9e5d22, 0xaf6c31, 0xbc7b41, 0xcc8a50, 0xd5935b,
0xe4a369, 0xf2b179, 0xffc289, 0xffcf97, 0xffdfa6, 0xffedb5,
0xfffdc4, 0x751618, 0x812324, 0x8f3134, 0x9d4043, 0xaa4e50,
0xb85e60, 0xc66d6f, 0xd57d7f, 0xde8787, 0xed9596, 0xfca4a5,
0xffb4b5, 0xffc2c4, 0xffd1d3, 0xffe0e1, 0xffeff0, 0x620e71,
0x6e1b7c, 0x7b2a8a, 0x8a3998, 0x9647a5, 0xa557b5, 0xb365c3,
0xc375d1, 0xcd7eda, 0xdc8de9, 0xea97f7, 0xf9acff, 0xffbaff,
0xffc9ff, 0xffd9ff, 0xffe8ff, 0x560f87, 0x611d90, 0x712c9e,
0x7f3aac, 0x8d48ba, 0x9b58c7, 0xa967d5, 0xb877e5, 0xc280ed,
0xd090fc, 0xdf9fff, 0xeeafff, 0xfcbdff, 0xffccff, 0xffdbff,
0xffeaff, 0x461695, 0x5122a0, 0x6032ac, 0x6e41bb, 0x7c4fc8,
0x8a5ed6, 0x996de3, 0xa87cf2, 0xb185fb, 0xc095ff, 0xcfa3ff,
0xdfb3ff, 0xeec1ff, 0xfcd0ff, 0xffdfff, 0xffefff, 0x212994,
0x2d359f, 0x3d44ad, 0x4b53ba, 0x5961c7, 0x686fd5, 0x777ee2,
0x878ef2, 0x9097fa, 0x96a6ff, 0xaeb5ff, 0xbfc4ff, 0xcdd2ff,
0xdae3ff, 0xeaf1ff, 0xfafeff, 0x0f3584, 0x1c418d, 0x2c509b,
0x3a5eaa, 0x486cb7, 0x587bc5, 0x678ad2, 0x7699e2, 0x80a2eb,
0x8fb2f9, 0x9ec0ff, 0xadd0ff, 0xbdddff, 0xcbecff, 0xdbfcff,
0xeaffff, 0x043f70, 0x114b79, 0x215988, 0x2f6896, 0x3e75a4,
0x4d83b2, 0x5c92c1, 0x6ca1d2, 0x74abd9, 0x83bae7, 0x93c9f6,
0xa2d8ff, 0xb1e6ff, 0xc0f5ff, 0xd0ffff, 0xdeffff, 0x005918,
0x006526, 0x0f7235, 0x1d8144, 0x2c8e50, 0x3b9d60, 0x4aac6f,
0x59bb7e, 0x63c487, 0x72d396, 0x82e2a5, 0x92f1b5, 0x9ffec3,
0xaeffd2, 0xbeffe2, 0xcefff1, 0x075c00, 0x146800, 0x227500,
0x328300, 0x3f910b, 0x4fa01b, 0x5eae2a, 0x6ebd3b, 0x77c644,
0x87d553, 0x96e363, 0xa7f373, 0xb3fe80, 0xc3ff8f, 0xd3ffa0,
0xe3ffb0, 0x1a5600, 0x286200, 0x367000, 0x457e00, 0x538c00,
0x629b07, 0x70a916, 0x80b926, 0x89c22f, 0x99d13e, 0xa8df4d,
0xb7ef5c, 0xc5fc6b, 0xd5ff7b, 0xe3ff8b, 0xf3ff99, 0x334b00,
0x405700, 0x4d6500, 0x5d7300, 0x6a8200, 0x7a9100, 0x889e0f,
0x98ae1f, 0xa1b728, 0xbac638, 0xbfd548, 0xcee458, 0xdcf266,
0xebff75, 0xfaff85, 0xffff95, 0x4b3c00, 0x584900, 0x655700,
0x746500, 0x817400, 0x908307, 0x9f9116, 0xaea126, 0xb7aa2e,
0xc7ba3e, 0xd5c74d, 0xe5d75d, 0xf2e56b, 0xfef47a, 0xffff8b,
0xffff9a, 0x602e00, 0x6d3a00, 0x7a4900, 0x895800, 0x95670a,
0xa4761b, 0xb2832a, 0xc2943a, 0xcb9d44, 0xdaac53, 0xe8ba62,
0xf8cb73, 0xffd77f, 0xffe791, 0xfff69f, 0xffffaf, };
private static class RGB {
public RGB() {
}
int r;
int g;
int b;
}
private static class Lab {
public Lab() {
}
double L;
double a;
double b;
}
static double[] calc = new double[256];
static RGB[] rgb;
static Lab[] cielab;
static RGB find_rgb;
static Lab find_lab;
static void RGB2LAB(RGB c, Lab lab) {
double var_R = c.r / 255.0; // R from 0 to 255
double var_G = c.g / 255.0; // G from 0 to 255
double var_B = c.b / 255.0; // B from 0 to 255
double X, Y, Z, var_X, var_Y, var_Z;
if (var_R > 0.04045)
var_R = Math.pow(((var_R + 0.055) / 1.055), 2.4);
else
var_R = var_R / 12.92;
if (var_G > 0.04045)
var_G = Math.pow(((var_G + 0.055) / 1.055), 2.4);
else
var_G = var_G / 12.92;
if (var_B > 0.04045)
var_B = Math.pow(((var_B + 0.055) / 1.055), 2.4);
else
var_B = var_B / 12.92;
var_R = var_R * 100.0;
var_G = var_G * 100.0;
var_B = var_B * 100.0;
// Observer. = 2°, Illuminant = D65
X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
var_X = X / 95.047; // ref_X = 95.047 Observer= 2°, Illuminant= D65
var_Y = Y / 100.000; // ref_Y = 100.000
var_Z = Z / 108.883; // ref_Z = 108.883
if (var_X > 0.008856) {
var_X = Math.pow(var_X, (1.0 / 3.0));
} else {
var_X = (7.787 * var_X) + (16.0 / 116.0);
}
if (var_Y > 0.008856) {
var_Y = Math.pow(var_Y, (1.0 / 3.0));
} else {
var_Y = (7.787 * var_Y) + (16.0 / 116.0);
}
if (var_Z > 0.008856) {
var_Z = Math.pow(var_Z, (1.0 / 3.0));
} else {
var_Z = (7.787 * var_Z) + (16.0 / 116.0);
}
lab.L = (116.0 * var_Y) - 16.0;
lab.a = 500.0 * (var_X - var_Y);
lab.b = 200.0 * (var_Y - var_Z);
}
public static final void main(String[] args) {
double Dl, Dc, Dh, C1, C2, a2, b2, m = 0xFFFFFF;
double Sl, Sc, Sh, K1 = 0.045, K2 = 0.015;
int i, j = -1;
if (args.length == 3) {
find_rgb = new RGB();
find_lab = new Lab();
find_rgb.r = Integer.parseInt(args[0]);
find_rgb.g = Integer.parseInt(args[1]);
find_rgb.b = Integer.parseInt(args[2]);
/* Make an RGB table from pre-computed values */
rgb = new RGB[256];
for (i = 0; i < 0x10; i++) {
for (j = 0; j < 0x10; j++) {
int c = real_pal[i * 0x10 + j];
int ir = (c >> 16) & 255;
int ig = (c >> 8) & 255;
int ib = c & 255;
rgb[i * 16 + j] = new RGB();
rgb[i * 16 + j].r = ir;
rgb[i * 16 + j].g = ig;
rgb[i * 16 + j].b = ib;
}
}
/* Make an Lab table from the RGB table */
cielab = new Lab[256];
for (i = 0; i < 256; i++) {
cielab[i] = new Lab();
RGB2LAB(rgb[i], cielab[i]);
}
/* What are we looking for */
RGB2LAB(find_rgb, find_lab);
/* Calc distances */
for (i = 0; i < 256; i++) {
C1 = Math.sqrt((find_lab.a * find_lab.a)
+ (find_lab.b * find_lab.b));
C2 = Math.sqrt((cielab[i].a * cielab[i].a)
+ (cielab[i].b * cielab[i].b));
Sl = 1.0;
Sc = 1.0 + K1 * C1;
Sh = 1.0 + K2 * C1;
Dl = find_lab.L - cielab[i].L;
Dc = C1 - C2;
a2 = find_lab.a - cielab[i].a;
a2 = a2 * a2;
b2 = find_lab.b - cielab[i].b;
b2 = b2 * b2;
Dh = Math.sqrt(a2 + b2 - (Dc * Dc));
calc[i] = (Dl / Sl) * (Dl / Sl);
calc[i] += (Dc / Sc) * (Dc / Sc);
calc[i] += (Dh / Sh) * (Dh / Sh);
}
for (i = 0; i < 256; i++) {
if (calc[i] < m) {
m = calc[i];
j = i;
}
}
// System.out.printf("R=%3d G=%3d B=%3d : $%02X Hue = %d Lum = %d\n",
// find_rgb.r, find_rgb.g, find_rgb.b, j, j / 16, j % 16);
} else {
System.out
.printf("Format:rgb2a8 Red Green Blue\n(values between 0 and 255)\n");
}
}
}

View File

@ -0,0 +1,361 @@
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
// TODO Class Atari8BitPaletteUtility2 is currently not used
public class Atari8BitPaletteUtility2 {
private final int PAL_ENTRIES_NO = 256;
private final int BAR_LINES_NO = 16;
private final int BAR_ENTRIES_NO = (PAL_ENTRIES_NO / BAR_LINES_NO);
static class RGB {
int R, G, B;
public static RGB FromArgb(int r1, int g1, int b1) {
RGB color = new RGB();
color.R = r1;
color.G = g1;
color.B = b1;
return color;
}
}
private RGB[] actual_pal = new RGB[PAL_ENTRIES_NO];
class LAB {
public double L;
public double a;
public double b;
}
private LAB[] cielab = new LAB[PAL_ENTRIES_NO];
private int min_y = 0, max_y = 0xf0;
private int colintens = 100;
private int colshift = 30;
// public int BlackLevel
// {
// get { return min_y; }
// set { min_y = value; CalcPaletteFromSettings(); Highlight =
// highlightColor; }
// }
//
// public int WhiteLevel
// {
// get { return max_y; }
// set { max_y = value; CalcPaletteFromSettings(); Highlight =
// highlightColor; }
// }
//
// public int Saturation
// {
// get { return colintens; }
// set { colintens = value; CalcPaletteFromSettings(); Highlight =
// highlightColor; }
// }
//
// public int ColorShift
// {
// get { return colshift; }
// set { colshift = value; CalcPaletteFromSettings(); Highlight =
// highlightColor; }
// }
private static int[] real_pal = { 0x323132, 0x3f3e3f, 0x4d4c4d, 0x5b5b5b,
0x6a696a, 0x797879, 0x888788, 0x979797, 0xa1a0a1, 0xafafaf,
0xbebebe, 0xcecdce, 0xdbdbdb, 0xebeaeb, 0xfafafa, 0xffffff,
0x612e00, 0x6c3b00, 0x7a4a00, 0x885800, 0x94670c, 0xa5761b,
0xb2842a, 0xc1943a, 0xca9d43, 0xdaad53, 0xe8bb62, 0xf8cb72,
0xffd87f, 0xffe88f, 0xfff79f, 0xffffae, 0x6c2400, 0x773000,
0x844003, 0x924e11, 0x9e5d22, 0xaf6c31, 0xbc7b41, 0xcc8a50,
0xd5935b, 0xe4a369, 0xf2b179, 0xffc289, 0xffcf97, 0xffdfa6,
0xffedb5, 0xfffdc4, 0x751618, 0x812324, 0x8f3134, 0x9d4043,
0xaa4e50, 0xb85e60, 0xc66d6f, 0xd57d7f, 0xde8787, 0xed9596,
0xfca4a5, 0xffb4b5, 0xffc2c4, 0xffd1d3, 0xffe0e1, 0xffeff0,
0x620e71, 0x6e1b7c, 0x7b2a8a, 0x8a3998, 0x9647a5, 0xa557b5,
0xb365c3, 0xc375d1, 0xcd7eda, 0xdc8de9, 0xea97f7, 0xf9acff,
0xffbaff, 0xffc9ff, 0xffd9ff, 0xffe8ff, 0x560f87, 0x611d90,
0x712c9e, 0x7f3aac, 0x8d48ba, 0x9b58c7, 0xa967d5, 0xb877e5,
0xc280ed, 0xd090fc, 0xdf9fff, 0xeeafff, 0xfcbdff, 0xffccff,
0xffdbff, 0xffeaff, 0x461695, 0x5122a0, 0x6032ac, 0x6e41bb,
0x7c4fc8, 0x8a5ed6, 0x996de3, 0xa87cf2, 0xb185fb, 0xc095ff,
0xcfa3ff, 0xdfb3ff, 0xeec1ff, 0xfcd0ff, 0xffdfff, 0xffefff,
0x212994, 0x2d359f, 0x3d44ad, 0x4b53ba, 0x5961c7, 0x686fd5,
0x777ee2, 0x878ef2, 0x9097fa, 0x96a6ff, 0xaeb5ff, 0xbfc4ff,
0xcdd2ff, 0xdae3ff, 0xeaf1ff, 0xfafeff, 0x0f3584, 0x1c418d,
0x2c509b, 0x3a5eaa, 0x486cb7, 0x587bc5, 0x678ad2, 0x7699e2,
0x80a2eb, 0x8fb2f9, 0x9ec0ff, 0xadd0ff, 0xbdddff, 0xcbecff,
0xdbfcff, 0xeaffff, 0x043f70, 0x114b79, 0x215988, 0x2f6896,
0x3e75a4, 0x4d83b2, 0x5c92c1, 0x6ca1d2, 0x74abd9, 0x83bae7,
0x93c9f6, 0xa2d8ff, 0xb1e6ff, 0xc0f5ff, 0xd0ffff, 0xdeffff,
0x005918, 0x006526, 0x0f7235, 0x1d8144, 0x2c8e50, 0x3b9d60,
0x4aac6f, 0x59bb7e, 0x63c487, 0x72d396, 0x82e2a5, 0x92f1b5,
0x9ffec3, 0xaeffd2, 0xbeffe2, 0xcefff1, 0x075c00, 0x146800,
0x227500, 0x328300, 0x3f910b, 0x4fa01b, 0x5eae2a, 0x6ebd3b,
0x77c644, 0x87d553, 0x96e363, 0xa7f373, 0xb3fe80, 0xc3ff8f,
0xd3ffa0, 0xe3ffb0, 0x1a5600, 0x286200, 0x367000, 0x457e00,
0x538c00, 0x629b07, 0x70a916, 0x80b926, 0x89c22f, 0x99d13e,
0xa8df4d, 0xb7ef5c, 0xc5fc6b, 0xd5ff7b, 0xe3ff8b, 0xf3ff99,
0x334b00, 0x405700, 0x4d6500, 0x5d7300, 0x6a8200, 0x7a9100,
0x889e0f, 0x98ae1f, 0xa1b728, 0xbac638, 0xbfd548, 0xcee458,
0xdcf266, 0xebff75, 0xfaff85, 0xffff95, 0x4b3c00, 0x584900,
0x655700, 0x746500, 0x817400, 0x908307, 0x9f9116, 0xaea126,
0xb7aa2e, 0xc7ba3e, 0xd5c74d, 0xe5d75d, 0xf2e56b, 0xfef47a,
0xffff8b, 0xffff9a, 0x602e00, 0x6d3a00, 0x7a4900, 0x895800,
0x95670a, 0xa4761b, 0xb2832a, 0xc2943a, 0xcb9d44, 0xdaac53,
0xe8ba62, 0xf8cb73, 0xffd77f, 0xffe791, 0xfff69f, 0xffffaf, };
private int highlightIndex = -1;
// public short A8Hue
// {
// get { return (short)(highlightIndex >> 4); }
// }
//
// public short A8Saturation
// {
// get { return (short)(highlightIndex & 15); }
// }
public int CalcHighlightLAB(RGB c) {
double[] calc = new double[PAL_ENTRIES_NO];
double l2, a2, b2, m = 0xFFFFFF;
int i, j = -1;
LAB lab = new LAB();
log("Looking for: R=" + c.R + ", G=" + c.G + ", B=" + c.B);
RGB2LAB(c, lab);
log("Looking for: L=" + lab.L + ", a=" + lab.a + ", b=" + lab.b);
for (i = 0; i < PAL_ENTRIES_NO; i++) {
l2 = lab.L - cielab[i].L;
l2 = l2 * l2;
a2 = lab.a - cielab[i].a;
a2 = a2 * a2;
b2 = lab.b - cielab[i].b;
b2 = b2 * b2;
calc[i] = l2 + a2 + b2;
}
for (i = 0; i < PAL_ENTRIES_NO; i++) {
log("Distance to: L=" + cielab[i].L + ", a=" + cielab[i].a + ", b="
+ cielab[i].b + " is " + calc[i]);
if (calc[i] < m) {
m = calc[i];
j = i;
log(" : New minimum!");
} else if (calc[i] == m) {
log(" : Equal min!");
} else {
log("");
}
}
log("Closest Color: m=" + m + " (R=" + actual_pal[j].R + ", G="
+ actual_pal[j].G + ", B=" + actual_pal[j].B + ")");
return j;
}
public int CalcHighlightRGB(RGB c) {
long[] calc = new long[PAL_ENTRIES_NO];
long r2, g2, b2, m = 0xFFFFFF, mg = 0xFFFFFF;
int i, j = -1, k = -1;
log("Looking for: R=" + c.R + ", G=" + c.G + ", B=" + c.B);
for (i = 0; i < PAL_ENTRIES_NO; i++) {
// (R-r)*(R-r) + (G-g)*(G-g) + (B-b)*(B-b)
r2 = c.R - actual_pal[i].R;
r2 = r2 * r2;
g2 = c.G - actual_pal[i].G;
g2 = g2 * g2;
b2 = c.B - actual_pal[i].B;
b2 = b2 * b2;
// calc[i] = (((512+rm)*r2)>>8) + 4*g2 + (((767-rm)*b2)>>8);
calc[i] = (2 * r2) + (4 * g2) + (3 * b2);
}
for (i = 0; i < 16; i++) {
log("Distance to: R=" + actual_pal[i].R + ", G=" + actual_pal[i].G
+ ", B=" + actual_pal[i].B + " is " + calc[i]);
if (calc[i] < mg) {
mg = calc[i];
k = i;
log(" : New minimum!");
} else if (calc[i] == mg) {
log(" : Equal min!");
} else {
log("");
}
}
for (i = 16; i < 256; i++) {
log("Distance to: R=" + actual_pal[i].R + ", G=" + actual_pal[i].G
+ ", B=" + actual_pal[i].B + " is " + calc[i]);
if (calc[i] < m) {
m = calc[i];
j = i;
log(" : New minimum!");
} else if (calc[i] == m) {
log(" : Equal min!");
} else {
log("");
}
}
log("Closest Grey: mg=" + mg + " (R=" + actual_pal[k].R + ", G="
+ actual_pal[k].G + ", B=" + actual_pal[k].B + ")");
log("Closest Color: m=" + m + " (R=" + actual_pal[j].R + ", G="
+ actual_pal[j].G + ", B=" + actual_pal[j].B + ")");
return j; // (mg < m) ? k : j;
}
private void log(String string) {
System.out.println(string);
}
void CalcPaletteFromSettings() {
int i, j;
/* Make an RGB table from computed values */
for (i = 0; i < 0x10; i++) {
int r, b;
double angle;
if (i == 0) {
r = b = 0;
} else {
angle = Math.PI * (i * (1.0 / 7) - colshift * 0.01);
r = (int) (Math.cos(angle) * colintens);
b = (int) (Math.cos(angle - Math.PI * (2.0 / 3)) * colintens);
}
for (j = 0; j < 0x10; j++) {
int y, r1, g1, b1;
y = (max_y * j + min_y * (0xf - j)) / 0xf;
r1 = y + r;
g1 = y - r - b;
b1 = y + b;
if (r1 > 0xff)
r1 = 0xff;
if (r1 < 0)
r1 = 0;
if (g1 > 0xff)
g1 = 0xff;
if (g1 < 0)
g1 = 0;
if (b1 > 0xff)
b1 = 0xff;
if (b1 < 0)
b1 = 0;
actual_pal[i * 16 + j] = RGB.FromArgb(r1, g1, b1);
}
}
}
public void AssignPalette(int[] new_pal) {
for (int i = 0; i < actual_pal.length; i++) {
int c = new_pal[i];
int r = (c >> 16) & 255;
int g = (c >> 8) & 255;
int b = c & 255;
actual_pal[i] = RGB.FromArgb(r, g, b);
}
CalcLAB();
}
private void RGB2LAB(RGB c, LAB lab) {
double var_R = c.R / 255.0; // R from 0 to 255
double var_G = c.G / 255.0; // G from 0 to 255
double var_B = c.B / 255.0; // B from 0 to 255
if (var_R > 0.04045)
var_R = Math.pow(((var_R + 0.055) / 1.055), 2.4);
else
var_R = var_R / 12.92;
if (var_G > 0.04045)
var_G = Math.pow(((var_G + 0.055) / 1.055), 2.4);
else
var_G = var_G / 12.92;
if (var_B > 0.04045)
var_B = Math.pow(((var_B + 0.055) / 1.055), 2.4);
else
var_B = var_B / 12.92;
var_R = var_R * 100.0;
var_G = var_G * 100.0;
var_B = var_B * 100.0;
// Observer. = 2°, Illuminant = D65
double X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
double Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
double Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
double var_X = X / 95.047; // ref_X = 95.047 Observer= 2°, Illuminant=
// D65
double var_Y = Y / 100.000; // ref_Y = 100.000
double var_Z = Z / 108.883; // ref_Z = 108.883
if (var_X > 0.008856)
var_X = Math.pow(var_X, (1.0 / 3.0));
else
var_X = (7.787 * var_X) + (16.0 / 116.0);
if (var_Y > 0.008856)
var_Y = Math.pow(var_Y, (1.0 / 3.0));
else
var_Y = (7.787 * var_Y) + (16.0 / 116.0);
if (var_Z > 0.008856)
var_Z = Math.pow(var_Z, (1.0 / 3.0));
else
var_Z = (7.787 * var_Z) + (16.0 / 116.0);
lab.L = (116.0 * var_Y) - 16.0;
lab.a = 500.0 * (var_X - var_Y);
lab.b = 200.0 * (var_Y - var_Z);
}
private void CalcLAB() {
for (int i = 0; i < PAL_ENTRIES_NO; i++) {
RGB2LAB(actual_pal[i], cielab[i]);
}
}
public Atari8BitPaletteUtility2() {
AssignPalette(real_pal);
}
public void MyColorView_Paint(GC gc) {
int width=100;
int height = 100;
int nWidth = (width - BAR_ENTRIES_NO) / BAR_ENTRIES_NO;
int nHeight = (height - BAR_LINES_NO) / BAR_LINES_NO;
int nOffsetX = (width - (nWidth + 1) * BAR_ENTRIES_NO) / 3 + 1;
int nOffsetY = (height - (nHeight + 1) * BAR_LINES_NO) / 3 + 1;
for (int i = 0; i < BAR_LINES_NO; i++) {
for (int j = 0; j < BAR_ENTRIES_NO; j++) {
int offset = i * BAR_ENTRIES_NO + j;
Rectangle rect = new Rectangle(nOffsetX + j * nWidth + j,
nOffsetY + i * nHeight + i, nWidth, nHeight);
// gc.setForeground(actual_pal[offset]);
gc.fillRectangle(rect);
if (offset == highlightIndex) {
rect = new Rectangle(rect.x - 1,
rect.y - 1, rect.width + 1,
rect.height + 1);
// gc.setForeground(Color.BLACK);
gc.fillRectangle(rect);
}
}
}
}
}

View File

@ -0,0 +1,299 @@
package com.wudsn.ide.gfx.converter.atari8bit;
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter
* Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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
* WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Utility class for Atari 8-bit specifics.
*
* @since 1.6.0
*/
public final class Atari8BitUtility {
/**
* Mapping of the 4 bit pixel values to the corresponding color register.
* Make sure not to modify contents of this array.
*/
public final static int[] GRAPHICS_10_REGISTERS = { 0, 1, 2, 3, 4, 5, 6, 7,
8, 8, 8, 8, 4, 5, 6, 7 };
/**
* Creation is private.
*
* @since 1.6.0
*/
private Atari8BitUtility() {
}
/**
* Gets a word stored lo/hi order.
*
* @param bytes
* The byte array, not empty and not <code>null</code>.
* @param offset
* The offset within the byte array, a non-negative integer.
* @return The length of the block header, a non-negative integer.
*
* @since 1.6.0
*/
public static int getWord(byte[] bytes, int offset) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return (bytes[offset] & 0xff) | ((bytes[offset + 1] & 0xff) << 8);
}
/**
* Gets the length of a binary COM block header within a byte array.
*
* @param bytes
* The byte array, may be empty, not <code>null</code>.
* @param offset
* The offset within the byte array, a non-negative integer.
* @return The length of the block header or <code>-1</code> if there is no
* valid block at the given offset.
*
* @since 1.6.0
*/
public static int getLengthFromBinaryHeader(byte[] bytes, int offset) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
if (offset < 0) {
throw new IllegalArgumentException(
"Parameter 'offset' must not be negative, specified value is "
+ offset + ".");
}
if (bytes.length >= offset + 6 && (bytes[offset + 0] & 0xff) == 0xff
&& (bytes[offset + 1] & 0xff) == 0xff) {
int startAddress = getWord(bytes, offset + 2);
int endAddress = getWord(bytes, offset + 4);
int length = endAddress - startAddress + 1;
return length;
}
return -1;
}
/**
* Unpack a Koala Painter compressed picture.
*
* @param data
* The byte array with the packed data, may be empty, not
* <code>null</code>.
* @param dataOffset
* The offset within data to start unpacking, a non-negative
* integer.
* @param dataLength
* The length of the data to be unpacked, a positive integer.
* @param cprtype
* The CPR packing type, either 0,1 or 2.
* @param unpackedData
* The byte array for the unpack data, must be 7680 bytes long.
* @return <code>true</code> if the data was unpacked successfully,
* <code>false</code> otherwise.
*
* @since 1.6.0
*/
public static boolean unpackKoala(byte[] data, int dataOffset,
int dataLength, int cprtype, byte[] unpackedData) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (dataOffset < 0) {
throw new IllegalArgumentException(
"Parameter 'dataOffset' must not be negative. Specified value is "
+ dataOffset + ".");
}
if (dataLength < 1) {
throw new IllegalArgumentException(
"Parameter 'dataLength' must be positive. Specified value is "
+ dataLength + ".");
}
int i;
int d;
switch (cprtype) {
case 0:
if (dataLength != 7680) {
return false;
}
System.arraycopy(data, dataOffset, unpackedData, 0, 7680);
return true;
case 1:
case 2:
break;
default:
return false;
}
i = 0;
d = dataOffset;
int dataEnd = d + dataLength;
for (;;) {
int c;
int len;
int b;
c = data[d++] & 0xff;
if (d > dataEnd) {
return false;
}
len = c & 0x7f;
if (len == 0) {
int h;
h = data[d++] & 0xff;
if (d > dataEnd) {
return false;
}
len = data[d++] & 0xff;
if (d > dataEnd) {
return false;
}
len += h << 8;
if (len == 0) {
return false;
}
}
b = -1;
do {
/*
* get byte of uncompressed block or if starting RLE block
*/
if (c >= 0x80 || b < 0) {
b = data[d++] & 0xff;
if (d > dataEnd) {
return false;
}
}
unpackedData[i] = (byte) b;
/* return if last byte written */
if (i >= 7679) {
return true;
}
if (cprtype == 2) {
i++;
} else {
i += 80;
if (i >= 7680) {
/*
* if in line 192, back to odd lines in the same column;
* if in line 193, go to even lines in the next column
*/
i -= (i < 7720) ? 191 * 40 : 193 * 40 - 1;
}
}
} while (--len > 0);
}
}
/**
* Unpack a compressed CIN picture.
*
* @param data
* The byte array with the packed data, may be empty, not
* <code>null</code>.
* @param dataOffset
* The offset within data to start unpacking, a non-negative
* integer.
* @param dataLength
* The length of the data to be unpacked, a positive integer.
* @param step
* The number of "columns", a non-negative integer.
* @param count
* The number of "lines", a non-negative integer.
* @param unpackedData
* The byte array for the unpack data, must be 7680 bytes long.
* @param unpackedDataOffset
* The offset within unpackedData to start unpacking, a
* non-negative integer.
* @return <code>true</code> if the data was unpacked successfully,
* <code>false</code> otherwise.
*
* @since 1.6.0
*/
public static boolean unpackCCI(byte data[], int dataOffset,
int dataLength, int step, int count, byte unpackedData[],
int unpackedDataOffset) {
int i = 0;
int d = 2;
int size = step * count;
int block_count = getWord(data, dataOffset);
while (block_count > 0) {
int c;
int len;
int b;
if (d > dataLength) {
return false;
}
c = data[dataOffset + d++] & 0xff;
len = (c & 0x7f) + 1;
b = -1;
do {
/*
* get byte if uncompressed block or if starting RLE block
*/
if (c < 0x80 || b < 0) {
if (d > dataLength) {
return false;
}
b = data[dataOffset + d++] & 0xff;
}
unpackedData[unpackedDataOffset + i] = (byte) b;
/* return if last byte written */
if (i >= size - 1) {
return true;
}
i += step;
if (i >= size) {
i -= size - 1;
}
} while (--len > 0);
block_count--;
}
if (d == dataLength) {
return true;
}
return false;
}
/**
* Determines if a byte array represents a valid Atari charset.
*
* @param bytes
* The byte array, may be empty, not <code>null</code>.
* @return <code>true</code> if the byte array represents a valid Atari
* charset, <code>false</code> otherwise.
*
* @since 1.6.0
*/
public static boolean isAtariCharset(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 1024
|| (bytes.length == 1024 + 6 && Atari8BitUtility
.getLengthFromBinaryHeader(bytes, 0) == 1024);
}
}

View File

@ -0,0 +1,308 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.eclipse.swt.graphics.ImageData;
import com.wudsn.ide.base.common.NumberFactory;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.ImageConverterData;
import com.wudsn.ide.gfx.converter.InverseBlock;
import com.wudsn.ide.gfx.converter.InverseBlockList;
import com.wudsn.ide.gfx.converter.Tile;
import com.wudsn.ide.gfx.converter.TileSet;
import com.wudsn.ide.gfx.converter.c64.C64Utility;
import com.wudsn.ide.gfx.converter.generic.CharMapConverter;
import com.wudsn.ide.gfx.converter.generic.CharMapMultiColorConverter;
public class CharMapGraphics12Converter extends
CharMapMultiColorConverter {
private static final Integer PF1 = NumberFactory.getInteger(1);
private static final Integer PF2 = NumberFactory.getInteger(2);
private static final Integer PF3 = NumberFactory.getInteger(3);
public CharMapGraphics12Converter() {
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns()
* (8 + data.getParameters().getSpacingWidth()));
data.setImageDataHeight(data.getParameters().getRows()
* (8 + data.getParameters().getSpacingWidth()));
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
return false;
}
public static void convertToFileData(ImageConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int pixelPerColumn = 4;
int pixelPerRow = 8;
TileSet tileSet;
tileSet = new TileSet(data.getImageData(), pixelPerColumn, pixelPerRow);
int screenWidth = 48;
int rowsPerCharset = 3;
// If the actual image is larger that the screen with, it cannot be
// processed..
if (tileSet.getColumns() > screenWidth) {
data.setTargetImageData(null);
}
// If the actual image is smaller that the screen with, it shall be
// centered.
int screenOffset = (screenWidth - tileSet.getColumns()) / 2;
boolean effect = data.getParameters().getConverterId()
.equals(CharMapGraphics12Converter.class.getName());
int charSets = (tileSet.getRows() + rowsPerCharset - 1)
/ rowsPerCharset;
byte[] screenBuffer = new byte[tileSet.getRows() * screenWidth];
byte[] charSetBuffer = new byte[1024 * charSets];
Integer gridColor = C64Utility.PINK;
Integer inverseConflictColor = C64Utility.YELLOW;
ImageData targetImageData = tileSet.createTiledImageData();
int screenCharacter = 0;
int charSetCount = -1;
for (int r = 0; r < tileSet.getRows(); r++) {
if (r % rowsPerCharset == 0) {
charSetCount++;
int charSetBufferOffset = charSetCount * 1024;
for (int i = 0; i < pixelPerRow; i++) {
charSetBuffer[charSetBufferOffset + i] = (byte) 0x55;
}
screenCharacter = 1;
}
for (int c = 0; c < tileSet.getColumns(); c++) {
// Create and analyze tile
Tile tile = tileSet.getTile(c, r);
Map<Integer, Integer> pixelMapping;
List<Integer> ignoredPixelColors;
InverseBlockList inverseBlockList;
pixelMapping = new TreeMap<Integer, Integer>();
ignoredPixelColors = new ArrayList<Integer>();
inverseBlockList = new InverseBlockList();
// TODO Make hard coded mapping real parameters
if (System.getProperty("user.name").equals("d025328")) {
if (r < 10 || r > 19) {
getTileMapping1(pixelMapping, ignoredPixelColors,
inverseBlockList);
} else {
getTileMapping2(pixelMapping, ignoredPixelColors,
inverseBlockList);
}
}
InverseBlock inverseBlock;
inverseBlock = inverseBlockList.getInverseBlock(c, r);
int inverseCharacter = 0x00;
Integer inverseColor;
if (inverseBlock != null) {
inverseColor = inverseBlock.getInverseColor();
if (tile.hasPixelColor(inverseColor)) {
// Collect all mappings which map to PF3.
List<Integer> pf3colors;
pf3colors = new ArrayList<Integer>();
for (Map.Entry<Integer, Integer> entry : pixelMapping
.entrySet()) {
if (entry.getValue().equals(PF3)) {
pf3colors.add(entry.getKey());
}
}
// Set inverse color to PF3 which becomes PF4 using the
// inverse
pixelMapping.put(inverseColor, PF3);
for (Integer pf3Color : pf3colors) {
if (tile.hasPixelColor(pf3Color)) {
tile.setInverseConflict(true);
break;
}
}
if (!tile.isInverseConflict()) {
// No conflict
ignoredPixelColors.add(inverseColor);
inverseCharacter = 0x80;
} else {
if (inverseBlock.isInverseIfConflict()) {
inverseCharacter = 0x80;
} else {
inverseCharacter = 0x00;
}
}
}
} else {
inverseColor = null;
}
screenBuffer[r * screenWidth + c + screenOffset] = (byte) (screenCharacter + inverseCharacter);
int charSetBufferOffset = charSetCount * 1024 + 8
* (screenCharacter & 0x7f);
screenCharacter++;
// Draw/copy tile.
Map<Integer, Integer> pixelColorCounts = tile
.getDistinctPixelColorCounts(ignoredPixelColors);
Integer lastRowMajorColor = null;
for (int r1 = 0; r1 < pixelPerRow; r1++) {
int my = r * (pixelPerRow + 1) + r1 + 1;
Map<Integer, Integer> rowPixelColorCounts = tile
.getDistinctLinePixelColorCounts(r1,
ignoredPixelColors);
int charSetByte = 0;
for (int c1 = 0; c1 < pixelPerColumn; c1++) {
int mx = c * (pixelPerColumn + 1) + c1 + 1;
Integer color = tile.getPixelColor(c1, r1);
Integer pixelBits = pixelMapping.get(color);
if (effect) {
if (pixelColorCounts.size() == 0) {
color = C64Utility.BLACK;
} else if (pixelColorCounts.size() == 1) {
color = Tile.getMajorColor(pixelColorCounts,
ignoredPixelColors);
} else if (rowPixelColorCounts.size() == 0) {
color = lastRowMajorColor;
} else if (rowPixelColorCounts.size() == 1) {
color = Tile.getMajorColor(rowPixelColorCounts,
ignoredPixelColors);
lastRowMajorColor = color;
}
if (color == null) {
color = C64Utility.BLACK;
}
if (color == inverseColor) {
color = inverseConflictColor;
}
}
targetImageData.setPixel(mx, my, color.intValue());
charSetByte = (charSetByte << 2);
if (pixelBits != null) {
charSetByte |= pixelBits.intValue();
}
}
charSetBuffer[charSetBufferOffset + r1] = (byte) charSetByte;
}
}
tileSet.drawTileBoundaries(targetImageData, gridColor,
inverseConflictColor);
}
data.setTargetFileBytes(CharMapConverter.CHAR_SET_FILE, charSetBuffer);
data.setTargetFileBytes(CharMapConverter.CHAR_MAP_FILE, screenBuffer);
data.setTargetImageData(targetImageData);
}
private static void getTileMapping2(Map<Integer, Integer> pixelMapping,
List<Integer> ignoredPixelColors, InverseBlockList inverseBlockList) {
pixelMapping.put(C64Utility.BLACK, PF1);
pixelMapping.put(C64Utility.WHITE, PF2);
pixelMapping.put(C64Utility.RED, PF3);
pixelMapping.put(C64Utility.LIGHT_GREEN, PF3);
ignoredPixelColors.add(C64Utility.BLACK);
ignoredPixelColors.add(C64Utility.WHITE);
// ignoredPixelColors.add(C64Utility.DARK_GRAY);
ignoredPixelColors.add(C64Utility.LIGHT_GREEN);
// Blue floor
inverseBlockList.add(0, 39, 8, 19, C64Utility.LIGHT_BLUE, true);
// Brown Ship
inverseBlockList.add(16, 18, 5, 7, C64Utility.BROWN, true);
// Blue Planet
inverseBlockList.add(0, 39, 0, 6, C64Utility.LIGHT_BLUE, true);
// Cybernoid
// inverseBlockList.add(0,
// 39, 8,
// 19,
// C64Utility.LIGHT_RED);
// // Red
// Yellow Explosion
inverseBlockList.add(4, 11, 20, 24, C64Utility.BROWN, false);
}
private static void getTileMapping1(Map<Integer, Integer> pixelMapping,
List<Integer> ignoredPixelColors, InverseBlockList inverseBlockList) {
pixelMapping.put(C64Utility.BLACK, PF1);
pixelMapping.put(C64Utility.WHITE, PF2);
pixelMapping.put(C64Utility.DARK_GRAY, PF3);
ignoredPixelColors.add(C64Utility.BLACK);
ignoredPixelColors.add(C64Utility.WHITE);
ignoredPixelColors.add(C64Utility.DARK_GRAY);
// Brown Ship
inverseBlockList.add(16, 18, 5, 7, C64Utility.BROWN, true);
// Blue Planet
inverseBlockList.add(0, 39, 0, 6, C64Utility.LIGHT_BLUE, true);
// Cybernoid
inverseBlockList.add(0, 39, 8, 19, C64Utility.LIGHT_RED, false);
// Yellow Explosion
inverseBlockList.add(4, 11, 20, 24, C64Utility.BROWN, true);
}
}

View File

@ -0,0 +1,4 @@
function convertToFileData(data) {
// This is not yet implemented
// com.wudsn.ide.gfx.converter.atari8bit.CharMapGraphics12Converter.convertToFileData(data);
}

View File

@ -0,0 +1,101 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
public class LinearBitMapAP3Converter extends LinearBitMapConverter {
public LinearBitMapAP3Converter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 15872;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
setImageSizeAndPalette(data, 40, 192, Palette.TRUE_COLOR, null);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 2);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int columns = data.getParameters().getColumns();
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
int offset1 = 8192;
int offset2 = 0;
int xpixels = 2;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1 = y1 + 1) {
for (int x1 = 0; x1 < columns; x1++) {
int c = data.getSourceFileByte(BIT_MAP_FILE, offset1++);
if (c < 0) {
return true;
}
int b = data.getSourceFileByte(BIT_MAP_FILE, offset2++);
if (b < 0) {
return true;
}
for (int x2 = 0; x2 < 2; x2++) {
int x = x1 * xpixels + x2;
int color = (c & mask_4bit[x2]) >>> shift_4bit[x2];
int brightness = (b & mask_4bit[x2]) >>> shift_4bit[x2];
int atariColor = color << 4 | brightness;
int directColor = paletteMapper.getRGBColor(atariColor);
data.setDirectPixel(x, y1, directColor);
}
}
}
return true;
}
}

View File

@ -0,0 +1,98 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
public class LinearBitMapAPACConverter extends LinearBitMapConverter {
public LinearBitMapAPACConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException("Parameter 'bytes' must not be null.");
}
return bytes.length > 40 && bytes.length % 40 == 0;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data, byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException("Parameter 'bytes' must not be null.");
}
setImageSizeAndPalette(data, 40, (bytes.length + 40 - 1) / 40, Palette.TRUE_COLOR, null);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 2);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException("Parameter 'data' must not be null.");
}
int columns = data.getParameters().getColumns();
int rows = data.getParameters().getRows();
int offset1 = 0;
int offset2 = columns;
int xpixels = 2;
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
for (int y1 = 0; y1 < rows; y1 = y1 + 1) {
for (int x1 = 0; x1 < columns; x1++) {
int c = data.getSourceFileByte(BIT_MAP_FILE, offset1++);
if (c < 0) {
return true;
}
int b = data.getSourceFileByte(BIT_MAP_FILE, offset2++);
if (b < 0) {
return true;
}
for (int x2 = 0; x2 < 2; x2++) {
int x = x1 * xpixels + x2;
int color = (c & mask_4bit[x2]) >>> shift_4bit[x2];
int brightness = (b & mask_4bit[x2]) >>> shift_4bit[x2];
int atariColor = color << 4 | brightness;
int directColor = paletteMapper.getRGBColor(atariColor);
data.setDirectPixel(x, y1, directColor);
}
}
offset1 = offset1 + columns;
offset2 = offset2 + columns;
}
return true;
}
}

View File

@ -0,0 +1,14 @@
function convertToFileData(data) {
var bpsl = (data.getImageDataWidth() + 1) / 2;
var bytes = []
var offset = 0;
for (var y = 0; y < data.getImageDataHeight(); y++) {
for (var x = 0; x < data.getImageDataWidth(); x = x + 2) {
var c1 = data.getPixelRGB(x, y);
var c2 = data.getPixelRGB(x + 1, y);
var b = c1 << 4 | c2;
bytes[offset++] = b;
}
}
data.setTargetFileObject(0, bytes);
}

View File

@ -0,0 +1,105 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
public class LinearBitMapAPCConverter extends LinearBitMapConverter {
public LinearBitMapAPCConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
// 7680 bytes of bitmap, optionally 40 bytes of text in ATASCII screen
// code
return bytes.length == 7680 || bytes.length == 7680 + 40;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
setImageSizeAndPalette(data, 40, 96, Palette.TRUE_COLOR, null);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 2);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int columns = data.getParameters().getColumns();
int offset1 = 0;
int offset2 = columns;
int xpixels = 2;
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
for (int y1 = 0; y1 < data.getParameters().getRows(); y1 = y1 + 1) {
for (int x1 = 0; x1 < columns; x1++) {
int c = data.getSourceFileByte(BIT_MAP_FILE, offset1++);
if (c < 0) {
return true;
}
int b = data.getSourceFileByte(BIT_MAP_FILE, offset2++);
if (b < 0) {
return true;
}
for (int x2 = 0; x2 < 2; x2++) {
int x = x1 * xpixels + x2;
int color = (c & mask_4bit[x2]) >>> shift_4bit[x2];
int brightness = (b & mask_4bit[x2]) >>> shift_4bit[x2];
int atariColor = color << 4 | brightness;
int directColor = paletteMapper.getRGBColor(atariColor);
data.setDirectPixel(x, y1, directColor);
}
}
offset1 = offset1 + columns;
offset2 = offset2 + columns;
}
return true;
}
}

View File

@ -0,0 +1,195 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.FilesConverterParameters.SourceFile;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
/**
* Converter for CCI and CIN files.
*
* @author Peter Dell
*
* @since 1.6.0
*/
public class LinearBitMapCINConverter extends LinearBitMapConverter {
public LinearBitMapCINConverter() {
}
private boolean isCIN(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 16384;
}
private boolean isCCI(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length > 7 && bytes[0] == 'C' && bytes[1] == 'I'
&& bytes[2] == 'N' && bytes[3] == ' ' && bytes[4] == '1'
&& bytes[5] == '.' && bytes[6] == '2' && bytes[7] == ' ';
}
private boolean unpackCCI(byte[] bytes, int offset, byte[] unpackedImage) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
if (offset < 0) {
throw new IllegalArgumentException(
"Parameter 'offset' must not be negative. Specified value is "
+ offset + ".");
}
if (unpackedImage == null) {
throw new IllegalArgumentException(
"Parameter 'unpackedImage' must not be null.");
}
// Compressed even lines of graphics 15 frame
int dataOffset = offset + 8;
int dataLength = Atari8BitUtility.getWord(bytes, dataOffset);
if (!Atari8BitUtility.unpackCCI(bytes, dataOffset + 2, dataLength, 80, 96,
unpackedImage, 0)) {
return false;
}
// Compressed odd lines of graphics 15 frame
dataOffset += 2 + dataLength;
dataLength = Atari8BitUtility.getWord(bytes, dataOffset);
if (!Atari8BitUtility.unpackCCI(bytes, dataOffset + 2, dataLength, 80, 96,
unpackedImage, 40)) {
return false;
}
// Compressed graphics 11
dataOffset += 2 + dataLength;
dataLength = Atari8BitUtility.getWord(bytes, dataOffset);
if (!Atari8BitUtility.unpackCCI(bytes, dataOffset + 2, dataLength, 40,
192, unpackedImage, 7680)) {
return false;
}
/* compressed color values for gr15 */
dataOffset += 2 + dataLength;
dataLength = Atari8BitUtility.getWord(bytes, dataOffset);
if (!Atari8BitUtility.unpackCCI(bytes, dataOffset + 2, dataLength, 1,
0x400, unpackedImage, 0x3C00)) {
return false;
}
dataOffset += 2 + dataLength;
return dataOffset == bytes.length;
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return isCIN(bytes) || isCCI(bytes);
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
setImageSizeAndPalette(data, 40, 192, Palette.TRUE_COLOR, null);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 4);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
byte[] bytes = data.getSourceFileBytes(BIT_MAP_FILE);
if (bytes == null) {
return false;
}
byte[] unpackedImage;
SourceFile sourceFile = data.getParameters()
.getSourceFile(BIT_MAP_FILE);
int offset = sourceFile.getOffset();
if (isCCI(bytes)) {
unpackedImage = new byte[16384];
if (!unpackCCI(bytes, offset, unpackedImage)) {
return false;
}
} else {
unpackedImage = bytes;
}
int xpixels = 4;
PaletteMapper paletteMapper=new Atari8BitPaletteMapper();
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
if (offset + 7680 >= unpackedImage.length) {
return true;
}
int b1 = unpackedImage[offset + 7680] & 0xff;
int b2 = unpackedImage[offset++] & 0xff;
for (int x2 = 0; x2 < 4; x2++) {
int x = x1 * xpixels + x2;
int x3 = x2 >>> 1;
int hue = (b1 & mask_4bit[x3]) >>> shift_4bit[x3];
int lumaRegister = (b2 & mask_2bit[x2]) >>> shift_2bit[x2];
int lumaOffset = 0x3c00 + lumaRegister * 0x100 + y1;
int luma = 0;
if (lumaOffset < unpackedImage.length) {
luma = unpackedImage[lumaOffset] & 0xe;
}
int color = paletteMapper.getRGBColor(hue << 4
| luma);
data.setDirectPixel(x, y1, color);
}
}
}
return true;
}
}

View File

@ -0,0 +1,122 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.PaletteType;
import com.wudsn.ide.gfx.model.PaletteUtility;
public class LinearBitMapCPRConverter extends LinearBitMapConverter {
public LinearBitMapCPRConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
if (bytes.length < 3) {
return false;
}
byte[] unpackedImage = new byte[7684];
boolean result = Atari8BitUtility.unpackKoala(bytes, 1, bytes.length - 1,
bytes[0] & 0xff, unpackedImage);
return result;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
byte[] unpackedImage = new byte[7684];
boolean result = Atari8BitUtility.unpackKoala(bytes, 1, bytes.length - 1,
bytes[0] & 0xff, unpackedImage);
if (!result) {
return;
}
RGB[] paletteColors;
paletteColors = PaletteUtility.getPaletteColors(
PaletteType.ATARI_DEFAULT, Palette.HIRES_1, null);
setImageSizeAndPalette(data, 40, 192, Palette.HIRES_1, paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 8);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
byte[] bytes = data.getSourceFileBytes(BIT_MAP_FILE);
if (bytes == null || bytes.length < 3) {
return false;
}
byte[] unpackedImage = new byte[7680];
boolean result = Atari8BitUtility.unpackKoala(bytes, 1, bytes.length - 1,
bytes[0] & 0xff, unpackedImage);
if (!result) {
return false;
}
int offset = 0;
int xpixels = 8;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
if (offset >= unpackedImage.length) {
return true;
}
int b = unpackedImage[offset++] & 0xff;
for (int x2 = 0; x2 < 8; x2++) {
int x = x1 * xpixels + x2;
int color = (b & mask_1bit[x2]) >>> shift_1bit[x2];
data.setPalettePixel(x, y1, color);
}
}
}
return true;
}
}

View File

@ -0,0 +1,100 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
public class LinearBitMapGHGConverter extends LinearBitMapConverter {
public LinearBitMapGHGConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 0x1f43 && Atari8BitUtility.getWord(bytes, 0) > 0
&& Atari8BitUtility.getWord(bytes, 0) <= 320
&& (bytes[2] & 0xff) > 0 && (bytes[2] & 0xff) <= 200;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
int columns = (Atari8BitUtility.getWord(bytes, 0) + 7) / 8;
int rows = (bytes[2] & 0xff);
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
RGB[] paletteColors = new RGB[2];
paletteColors[0] = paletteMapper.getRGB(12);
paletteColors[1] = paletteMapper.getRGB(2);
setImageSizeAndPalette(data, columns, rows, Palette.HIRES_MANUAL,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 8);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset = 3;
int xpixels = 8;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b = data.getSourceFileByte(BIT_MAP_FILE, offset++);
if (b < 0) {
return true;
}
for (int x2 = 0; x2 < 8; x2++) {
int x = x1 * xpixels + x2;
int color = (b & mask_1bit[x2]) >>> shift_1bit[x2];
data.setPalettePixel(x, y1, color);
}
}
}
return true;
}
}

View File

@ -0,0 +1,64 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
public class LinearBitMapGraphics10Converter extends LinearBitMapConverter {
public LinearBitMapGraphics10Converter() {
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 8);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset = 0;
int xpixels = 2;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b = data.getSourceFileByte(BIT_MAP_FILE, offset++);
if (b < 0) {
return true;
}
for (int x2 = 0; x2 < 2; x2++) {
int x = x1 * xpixels + x2;
int color = (b & mask_4bit[x2]) >>> shift_4bit[x2];
data.setDirectPixel(x, y1, color * 0x101010);
}
}
}
return true;
}
}

View File

@ -0,0 +1,14 @@
function convertToFileData(data) {
var bpsl = (data.getImageDataWidth() + 1) / 2;
var bytes = [];
var offset = 0;
for (var y = 0; y < data.getImageDataHeight(); y++) {
for (var x = 0; x < data.getImageDataWidth(); x = x + 2) {
var c1 = data.getPixel(x, y);
var c2 = data.getPixel(x + 1, y);
var b = c1 << 4 | c2;
bytes[offset++] = b;
}
}
data.setTargetFileObject(0, bytes);
}

View File

@ -0,0 +1,99 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.PaletteType;
import com.wudsn.ide.gfx.model.PaletteUtility;
public class LinearBitMapGraphics15Converter extends LinearBitMapConverter {
public LinearBitMapGraphics15Converter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 7680;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
int columns = 40;
int rows = (bytes.length + columns - 1) / columns;
RGB[] paletteColors;
paletteColors = PaletteUtility.getPaletteColors(
PaletteType.ATARI_DEFAULT, Palette.MULTI_1, null);
setImageSizeAndPalette(data, columns, rows, Palette.MULTI_1,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 4);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset = 0;
int xpixels = 4;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b = data.getSourceFileByte(BIT_MAP_FILE, offset++);
if (b < 0) {
return true;
}
for (int x2 = 0; x2 < 4; x2++) {
int x = x1 * xpixels + x2;
int color = (b & mask_2bit[x2]) >>> shift_2bit[x2];
data.setPalettePixel(x, y1, color);
}
}
}
return true;
}
}

View File

@ -0,0 +1,16 @@
function convertToFileData(data) {
var bpsl = (data.getImageDataWidth() + 3) / 4;
var bytes = [];
var offset = 0;
for (var y = 0; y < data.getImageDataHeight(); y++) {
for (var x = 0; x < data.getImageDataWidth(); x = x + 4) {
var c1,c2,c3,c4;
c1 = data.getPixel(x, y) & 0x3;
c2 = data.getPixel(x+1, y) & 0x3;
c3 = data.getPixel(x+2, y) & 0x3;
c4 = data.getPixel(x+3, y) & 0x3;
bytes[offset++] = c1 << 6 | c2 << 4 | c3 << 2 | c4;
}
}
data.setTargetFileObject(0, bytes);
}

View File

@ -0,0 +1,93 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.PaletteType;
import com.wudsn.ide.gfx.model.PaletteUtility;
public class LinearBitMapGraphics8Converter extends LinearBitMapConverter {
public LinearBitMapGraphics8Converter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 7680;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
RGB[] paletteColors;
paletteColors = PaletteUtility.getPaletteColors(
PaletteType.ATARI_DEFAULT, Palette.HIRES_1, null);
setImageSizeAndPalette(data, 40, 192, Palette.HIRES_1, paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 8);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset = 0;
int xpixels = 8;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b = data.getSourceFileByte(BIT_MAP_FILE, offset++);
if (b < 0) {
return true;
}
for (int x2 = 0; x2 < 8; x2++) {
int x = x1 * xpixels + x2;
int color = (b & mask_1bit[x2]) >>> shift_1bit[x2];
data.setPalettePixel(x, y1, color);
}
}
}
return true;
}
}

View File

@ -0,0 +1,19 @@
function convertToFileData(data) {
var bpsl = (data.getImageDataWidth() + 7) / 8;
var bytes = [];
var offset = 0;
for (var y = 0; y < data.getImageDataHeight(); y++) {
for (var x = 0; x < data.getImageDataWidth(); x = x + 8) {
var b = 0;
for (var p = 0; p < 8; p++) {
var color;
color = data.getPixel(x + p, y);
if (color != 0) {
b = b | 1 << 7 - p;
}
}
bytes[offset++] = b;
}
}
data.setTargetFileObject(0, bytes);
}

View File

@ -0,0 +1,96 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.PaletteType;
import com.wudsn.ide.gfx.model.PaletteUtility;
public class LinearBitMapGraphics9Converter extends LinearBitMapConverter {
public LinearBitMapGraphics9Converter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 7680;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
RGB[] paletteColors;
paletteColors = PaletteUtility.getPaletteColors(
PaletteType.ATARI_DEFAULT, Palette.GTIA_GREY_1, null);
setImageSizeAndPalette(data, 40, 192, Palette.GTIA_GREY_1,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 2);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset = 0;
int xpixels = 2;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b = data.getSourceFileByte(BIT_MAP_FILE, offset++);
if (b < 0) {
return true;
}
for (int x2 = 0; x2 < 2; x2++) {
int x = x1 * xpixels + x2;
int color = (b & mask_4bit[x2]) >>> shift_4bit[x2];
data.setPalettePixel(x, y1, color);
}
}
}
return true;
}
}

View File

@ -0,0 +1,14 @@
function convertToFileData(data) {
var bpsl = (data.getImageDataWidth() + 1) / 2;
var bytes = [];
var offset = 0;
for (var y = 0; y < data.getImageDataHeight(); y++) {
for (var x = 0; x < data.getImageDataWidth(); x = x + 2) {
var c1 = data.getPixel(x, y);
var c2 = data.getPixel(x + 1, y);
var b = c1 << 4 | c2;
bytes[offset++] = b;
}
}
data.setTargetFileObject(0, bytes);
}

View File

@ -0,0 +1,193 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.RBGUtility;
public class LinearBitMapHIPConverter extends LinearBitMapConverter {
public LinearBitMapHIPConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
// HIP image with binary file headers. Two concatenated COM files.
int frame1Length = Atari8BitUtility.getLengthFromBinaryHeader(bytes, 0);
if (frame1Length > 0 && frame1Length * 2 + 12 == bytes.length
&& frame1Length % 40 == 0) {
int frame2Length = Atari8BitUtility.getLengthFromBinaryHeader(bytes,
frame1Length + 6);
if (frame2Length == frame1Length) {
return true;
}
}
// HIP image with graphics 10 palette.
else if ((bytes.length - 9) % 80 == 0) {
return true;
}
return false;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
// HIP image with binary file headers. Two concatenated COM files.
int rows;
int frame1Length = Atari8BitUtility.getLengthFromBinaryHeader(bytes, 0);
if (frame1Length > 0 && frame1Length * 2 + 12 == bytes.length
&& frame1Length % 40 == 0) {
int frame2Length = Atari8BitUtility.getLengthFromBinaryHeader(bytes,
frame1Length + 6);
if (frame2Length != frame1Length) {
throw new IllegalStateException("Inconsistent file");
}
rows = frame1Length / 40;
}
// hip image with gr10 palette.
else if ((bytes.length - 9) % 80 == 0) {
rows = (bytes.length - 9) / 80;
} else {
throw new IllegalStateException("Inconsistent file");
}
setImageSizeAndPalette(data, 40, rows, Palette.TRUE_COLOR, null);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 4 + 1);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int rows = data.getParameters().getRows();
int columns = data.getParameters().getColumns();
PaletteMapper paletteMapper=new Atari8BitPaletteMapper();
// Assume the binary is already merged in case of a 160012 bytes HIP.
int offset9, offset10, offsetPalette;
byte[] sourceFileBytes = data.getSourceFileBytes(BIT_MAP_FILE);
if (sourceFileBytes == null) {
return false;
}
// Assume grey scale colors by default.
int[] graphics10Colors = { 0, 0, 2, 4, 6, 8, 10, 12, 14 };
// Compute the offsets in the file.
int frameSize = rows * columns;
int rest = sourceFileBytes.length - 2 * frameSize;
if (rest == 0 || rest == 9) {
// In this case the graphics 9 picture comes first
offset9 = 0;
offset10 = offset9 + 0 + frameSize;
offsetPalette = offset10 + frameSize;
if (rest == 9) {
for (int i = 0; i < 9; i++) {
graphics10Colors[i] = sourceFileBytes[offsetPalette + i];
}
}
} else if (rest == 12) {
// In this case the graphics 10 picture comes first
offset10 = 6;
offset9 = offset10 + 6 + frameSize;
} else {
return false;
}
int[] buffer1 = new int[columns * 4 + 1];
int[] buffer2 = new int[columns * 4 + 1];
for (int y1 = 0; y1 < rows; y1++) {
for (int x1 = 0; x1 < columns; x1++) {
int byte9 = data.getSourceFileByte(BIT_MAP_FILE, offset9++);
if (byte9 < 0) {
return true;
}
int byte10 = data.getSourceFileByte(BIT_MAP_FILE, offset10++);
if (byte10 < 0) {
return true;
}
// Byte 1 is the GTIA 9 byte, take the values as brightness
// values
int brightness1 = (byte9 & mask_4bit[0]) >>> shift_4bit[0];
int brightness2 = (byte9 & mask_4bit[1]) >>> shift_4bit[1];
// Byte 2 is the GTIA 10 byte, take the values from the GTIA 10
// palette
int brightness3 = (byte10 & mask_4bit[0]) >>> shift_4bit[0];
int brightness4 = (byte10 & mask_4bit[1]) >>> shift_4bit[1];
brightness3 = graphics10Colors[Atari8BitUtility.GRAPHICS_10_REGISTERS[brightness3]];
brightness4 = graphics10Colors[Atari8BitUtility.GRAPHICS_10_REGISTERS[brightness4]];
// Put the color values in the row buffer, shifted by 1 pixel
int x = x1 << 2;
buffer1[x + 0] = brightness1;
buffer1[x + 1] = brightness1;
buffer1[x + 2] = brightness2;
buffer1[x + 3] = brightness2;
buffer2[x + 1] = brightness3;
buffer2[x + 2] = brightness3;
buffer2[x + 3] = brightness4;
buffer2[x + 4] = brightness4;
}
// Merge the two buffers into combined color values.
for (int x = 0; x < buffer1.length; x++) {
int atariColor = RBGUtility.combineRGBColor(
paletteMapper.getRGBColor(buffer1[x]),
paletteMapper.getRGBColor(buffer2[x]));
data.setDirectPixel(x, y1, atariColor);
}
}
return true;
}
}

View File

@ -0,0 +1,31 @@
function convertToFileData(data) {
var bpsl = (data.getImageDataWidth() + 1) / 2;
var bptl = bpsl / 2;
var bytes = [];
var offset = 0;
for (var y = 0; y < data.getImageDataHeight(); y++) {
for (var x = 0; x < data.getImageDataWidth(); x = x + 4) {
var c1;
var c2;
c1 = data.getPixel(x, y);
if (x+2 < data.getImageDataWidth() ){
c2 = data.getPixel(x+2, y);
} else {
c2 = 0;
}
bytes[offset] = (color1 << 4 | color2);
c1 = data.getPixel(x+1, y);
if (x+3 < data.getImageDataWidth() ){
c2 = data.getPixel(x+3, y);
} else {
c2 = 0;
}
bytes[offset] = (color1 << 4 | color2);
}
bytes[offset++] = b;
}
offset += bptl;
}
data.setTargetFileObject(0, bytes);
}

View File

@ -0,0 +1,122 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.RBGUtility;
public class LinearBitMapHR2Converter extends LinearBitMapConverter {
public LinearBitMapHR2Converter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 16006;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
PaletteMapper paletteMapper=new Atari8BitPaletteMapper();
RGB[] paletteColors = new RGB[8];
RGB[] palette1Colors = new RGB[2];
RGB[] palette2Colors = new RGB[4];
palette1Colors[0] = paletteMapper.getRGB(bytes[16000] & 0xfe);
palette1Colors[1] = paletteMapper.getRGB(bytes[16001] & 0xfe);
palette2Colors[0] = paletteMapper.getRGB(bytes[16002] & 0xfe);
palette2Colors[1] = paletteMapper.getRGB(bytes[16003] & 0xfe);
palette2Colors[2] = paletteMapper.getRGB(bytes[16004] & 0xfe);
palette2Colors[3] = paletteMapper.getRGB(bytes[16005] & 0xfe);
// Compute mixed interlace colors.
for (int x1 = 0; x1 < palette1Colors.length; x1++) {
for (int x2 = 0; x2 < palette2Colors.length; x2++) {
paletteColors[x1 * palette2Colors.length + x2] = RBGUtility
.combineRGB(palette1Colors[x1], palette2Colors[x2]);
}
}
setImageSizeAndPalette(data, 40, 200, Palette.MULTI_MANUAL,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 8);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset = 0;
int xpixels = 8;
int frameSize = 8000;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b1 = data.getSourceFileByte(BIT_MAP_FILE, offset);
if (b1 < 0) {
return true;
}
int b2 = data.getSourceFileByte(BIT_MAP_FILE, offset
+ frameSize);
if (b2 < 0) {
return true;
}
offset++;
for (int x2 = 0; x2 < 8; x2++) {
int x = x1 * xpixels + x2;
// Graphics 8
int color1 = (b1 & mask_1bit[x2]) >>> shift_1bit[x2];
// Graphics 15, half resolution
int color2 = (b2 & mask_2bit[x2 >>> 1]) >>> shift_2bit[x2 >>> 1];
data.setPalettePixel(x, y1, (color1 << 2) + color2);
}
}
}
return true;
}
}

View File

@ -0,0 +1,108 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.RBGUtility;
import com.wudsn.ide.gfx.model.PaletteUtility;
public class LinearBitMapHRConverter extends LinearBitMapConverter {
public LinearBitMapHRConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 16384;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
RGB[] paletteColors = new RGB[3];
paletteColors[0] = PaletteUtility.BLACK;
paletteColors[2] = PaletteUtility.WHITE;
// Compute mixed interlace colors.
paletteColors[1] = RBGUtility.combineRGB(paletteColors[0],
paletteColors[2]);
setImageSizeAndPalette(data, 32, 239, Palette.MULTI_MANUAL,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 8);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset = 0;
int xpixels = 8;
int frameSize = 8192;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b1 = data.getSourceFileByte(BIT_MAP_FILE, offset);
if (b1 < 0) {
return true;
}
int b2 = data.getSourceFileByte(BIT_MAP_FILE, offset
+ frameSize);
if (b2 < 0) {
return true;
}
offset++;
for (int x2 = 0; x2 < 8; x2++) {
int x = x1 * xpixels + x2;
int color1 = (b1 & mask_1bit[x2]) >>> shift_1bit[x2];
int color2 = (b2 & mask_1bit[x2]) >>> shift_1bit[x2];
data.setPalettePixel(x, y1, color1 + color2);
}
}
}
return true;
}
}

View File

@ -0,0 +1,102 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
public class LinearBitMapILCConverter extends LinearBitMapConverter {
public LinearBitMapILCConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 15360;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
setImageSizeAndPalette(data, 40, 192, Palette.TRUE_COLOR, null);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 2);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int columns = data.getParameters().getColumns();
int offset1 = 7680;
int offset2 = 0;
int xpixels = 2;
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
for (int y1 = 0; y1 < data.getParameters().getRows(); y1 = y1 + 1) {
for (int x1 = 0; x1 < columns; x1++) {
int c = data.getSourceFileByte(BIT_MAP_FILE, offset1++);
if (c < 0) {
return true;
}
int b = data.getSourceFileByte(BIT_MAP_FILE, offset2++);
if (b < 0) {
return true;
}
for (int x2 = 0; x2 < 2; x2++) {
int x = x1 * xpixels + x2;
int color = (c & mask_4bit[x2]) >>> shift_4bit[x2];
int brightness = (b & mask_4bit[x2]) >>> shift_4bit[x2];
int atariColor = color << 4 | brightness;
int directColor = paletteMapper
.getRGBColor(atariColor);
data.setDirectPixel(x, y1, directColor);
}
}
}
return true;
}
}

View File

@ -0,0 +1,117 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.RBGUtility;
/**
* The valid bit pattern combinations from the two images are: (0,0)=0, (0,1)=1,
* (1,1)=2, (1,2)=3, (2,2)=4, (2,3)=5, (3,3)=6
*/
public class LinearBitMapINPConverter extends LinearBitMapConverter {
public LinearBitMapINPConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 16004 || bytes.length == 16052;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
RGB[] paletteColors = new RGB[7];
paletteColors[0] = paletteMapper.getRGB(bytes[16000] & 0xfe);
paletteColors[2] = paletteMapper.getRGB(bytes[16001] & 0xfe);
paletteColors[4] = paletteMapper.getRGB(bytes[16002] & 0xfe);
paletteColors[6] = paletteMapper.getRGB(bytes[16003] & 0xfe);
// Compute mixed interlace colors.
paletteColors[1] = RBGUtility.combineRGB(paletteColors[0],
paletteColors[2]);
paletteColors[3] = RBGUtility.combineRGB(paletteColors[2],
paletteColors[4]);
paletteColors[5] = RBGUtility.combineRGB(paletteColors[4],
paletteColors[6]);
setImageSizeAndPalette(data, 40, 200, Palette.MULTI_MANUAL,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 4);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset = 0;
int xpixels = 4;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b1 = data.getSourceFileByte(BIT_MAP_FILE, offset + 8000);
int b2 = data.getSourceFileByte(BIT_MAP_FILE, offset++);
if (b1 < 0 || b2 < 0) {
return true;
}
for (int x2 = 0; x2 < 4; x2++) {
int x = x1 * xpixels + x2;
int color1 = (b1 & mask_2bit[x2]) >>> shift_2bit[x2];
int color2 = (b2 & mask_2bit[x2]) >>> shift_2bit[x2];
data.setPalettePixel(x, y1, color1 + color2);
}
}
}
return true;
}
}

View File

@ -0,0 +1,147 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.RBGUtility;
/**
* The valid bit pattern combinations from the two images are: (0,0)=0, (0,1)=1,
* (1,1)=2, (1,2)=3, (2,2)=4, (2,3)=5, (3,3)=6
*/
public class LinearBitMapINTConverter extends LinearBitMapConverter {
public LinearBitMapINTConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
if (bytes.length < 10) {
return false;
}
if (bytes[0] != (byte) 'I'
|| bytes[1] != (byte) 'N'
|| bytes[2] != (byte) 'T'
|| bytes[3] != (byte) '9'
|| bytes[4] != (byte) '5'
|| bytes[5] != (byte) 'a'
|| bytes[6] == (byte) 0
|| (bytes[6] & 0xff) > 40
|| bytes[7] == (byte) 0
|| (bytes[7] & 0xff) > 239
|| bytes[8] != (byte) 0x0f
|| bytes[9] != (byte) 0x2b
|| 18 + (bytes[6] & 0xff) * (bytes[7] & 0xff) * 2 != bytes.length) {
return false;
}
return true;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
int rows;
int columns;
rows = bytes[7] & 0xff;
columns = bytes[6] & 0xff;
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
RGB[] paletteColors = new RGB[16];
RGB[] palette1Colors = new RGB[4];
RGB[] palette2Colors = new RGB[4];
palette1Colors[0] = paletteMapper.getRGB(bytes[10] & 0xfe);
palette1Colors[1] = paletteMapper.getRGB(bytes[11] & 0xfe);
palette1Colors[2] = paletteMapper.getRGB(bytes[12] & 0xfe);
palette1Colors[3] = paletteMapper.getRGB(bytes[13] & 0xfe);
palette2Colors[0] = paletteMapper.getRGB(bytes[14] & 0xfe);
palette2Colors[1] = paletteMapper.getRGB(bytes[15] & 0xfe);
palette2Colors[2] = paletteMapper.getRGB(bytes[16] & 0xfe);
palette2Colors[3] = paletteMapper.getRGB(bytes[17] & 0xfe);
// Compute mixed interlace colors.
for (int x1 = 0; x1 < 4; x1++) {
for (int x2 = 0; x2 < 4; x2++) {
paletteColors[x1 * 4 + x2] = RBGUtility.combineRGB(
palette1Colors[x1], palette2Colors[x2]);
}
}
setImageSizeAndPalette(data, columns, rows, Palette.MULTI_MANUAL,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 4);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset1 = 18;
int offset2 = offset1 + data.getParameters().getRows()
* data.getParameters().getColumns();
int xpixels = 4;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b1 = data.getSourceFileByte(BIT_MAP_FILE, offset1++);
int b2 = data.getSourceFileByte(BIT_MAP_FILE, offset2++);
if (b1 < 0 || b2 < 0) {
return true;
}
for (int x2 = 0; x2 < 4; x2++) {
int x = x1 * xpixels + x2;
int color1 = (b1 & mask_2bit[x2]) >>> shift_2bit[x2];
int color2 = (b2 & mask_2bit[x2]) >>> shift_2bit[x2];
int color = 4 * color1 + color2;
data.setPalettePixel(x, y1, color);
}
}
}
return true;
}
}

View File

@ -0,0 +1,147 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
public class LinearBitMapKoalaConverter extends LinearBitMapConverter {
public LinearBitMapKoalaConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
if (bytes.length < 22) {
return false;
}
if ((bytes[0] != (byte) 0xff || bytes[1] != (byte) 0x80
|| bytes[2] != (byte) 0xc9 || bytes[3] != (byte) 0xc7
|| bytes[4] < (byte) 0x1a || (bytes[4] & 0xff) >= bytes.length
|| bytes[5] != (byte) 0 || bytes[6] != (byte) 1
|| bytes[8] != (byte) 0x0e || bytes[9] != (byte) 0
|| bytes[10] != (byte) 40 || bytes[11] != (byte) 0
|| bytes[12] != (byte) 192 || bytes[20] != (byte) 0 || bytes[21] != (byte) 0)) {
return false;
}
byte[] unpackedImage = new byte[7684];
boolean result = Atari8BitUtility.unpackKoala(bytes,
(bytes[4] & 0xff) + 1, bytes.length - (bytes[4] & 0xff) - 1,
bytes[7] & 0xff, unpackedImage);
return result;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
byte[] unpackedImage = new byte[7684];
boolean result = Atari8BitUtility.unpackKoala(bytes,
(bytes[4] & 0xff) + 1, bytes.length - (bytes[4] & 0xff) - 1,
bytes[7] & 0xff, unpackedImage);
if (!result) {
throw new IllegalStateException("canConverterToImage() not called");
}
unpackedImage[7680] = bytes[17];
unpackedImage[7681] = bytes[13];
unpackedImage[7682] = bytes[14];
unpackedImage[7683] = bytes[15];
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
RGB[] paletteColors = new RGB[4];
paletteColors[0] = paletteMapper.getRGB(unpackedImage[7680] & 0xfe);
paletteColors[1] = paletteMapper.getRGB(unpackedImage[7681] & 0xfe);
paletteColors[2] = paletteMapper.getRGB(unpackedImage[7682] & 0xfe);
paletteColors[3] = paletteMapper.getRGB(unpackedImage[7683] & 0xfe);
setImageSizeAndPalette(data, 40, 192, Palette.MULTI_MANUAL,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 4);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
byte[] bytes = data.getSourceFileBytes(BIT_MAP_FILE);
if (bytes == null || bytes.length < 8) {
return false;
}
byte[] unpackedImage = new byte[7684];
boolean result;
result = Atari8BitUtility.unpackKoala(bytes, (bytes[4] & 0xff) + 1,
bytes.length - (bytes[4] & 0xff) - 1, bytes[7] & 0xff,
unpackedImage);
if (!result) {
return false;
}
int offset = 0;
int xpixels = 4;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
if (offset >= unpackedImage.length) {
return true;
}
int b = unpackedImage[offset++] & 0xff;
for (int x2 = 0; x2 < 4; x2++) {
int x = x1 * xpixels + x2;
int color = (b & mask_2bit[x2]) >>> shift_2bit[x2];
data.setPalettePixel(x, y1, color);
}
}
}
return true;
}
}

View File

@ -0,0 +1,123 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.RBGUtility;
public class LinearBitMapMCPConverter extends LinearBitMapConverter {
public LinearBitMapMCPConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 16008;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
RGB[] paletteColors = new RGB[16];
RGB[] palette1Colors = new RGB[4];
RGB[] palette2Colors = new RGB[4];
palette1Colors[0] = paletteMapper.getRGB(bytes[16003] & 0xfe);
palette1Colors[1] = paletteMapper.getRGB(bytes[16000] & 0xfe);
palette1Colors[2] = paletteMapper.getRGB(bytes[16001] & 0xfe);
palette1Colors[3] = paletteMapper.getRGB(bytes[16002] & 0xfe);
palette2Colors[0] = paletteMapper.getRGB(bytes[16007] & 0xfe);
palette2Colors[1] = paletteMapper.getRGB(bytes[16004] & 0xfe);
palette2Colors[2] = paletteMapper.getRGB(bytes[16005] & 0xfe);
palette2Colors[3] = paletteMapper.getRGB(bytes[16006] & 0xfe);
// Compute mixed interlace colors.
for (int x1 = 0; x1 < 4; x1++) {
for (int x2 = 0; x2 < 4; x2++) {
paletteColors[x1 * 4 + x2] = RBGUtility.combineRGB(
palette1Colors[x1], palette2Colors[x2]);
}
}
setImageSizeAndPalette(data, 40, 200, Palette.MULTI_MANUAL,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 4);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset = 0;
int xpixels = 4;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b1 = data.getSourceFileByte(BIT_MAP_FILE, offset + 8000);
int b2 = data.getSourceFileByte(BIT_MAP_FILE, offset++);
if (b1 < 0 || b2 < 0) {
return true;
}
for (int x2 = 0; x2 < 4; x2++) {
int x = x1 * xpixels + x2;
int color1 = (b1 & mask_2bit[x2]) >>> shift_2bit[x2];
int color2 = (b2 & mask_2bit[x2]) >>> shift_2bit[x2];
int color;
if ((y1 & 1) == 1) {
color = 4 * color1 + color2;
} else {
color = 4 * color2 + color1;
}
data.setPalettePixel(x, y1, color);
}
}
}
return true;
}
}

View File

@ -0,0 +1,107 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import org.eclipse.swt.graphics.RGB;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.PaletteType;
import com.wudsn.ide.gfx.model.PaletteUtility;
public class LinearBitMapMicroPainterConverter extends LinearBitMapConverter {
public LinearBitMapMicroPainterConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
return bytes.length == 7680 || bytes.length == 7684;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
RGB[] paletteColors;
if (bytes.length == 7684) {
paletteColors = new RGB[4];
paletteColors[0] = paletteMapper.getRGB(bytes[7680] & 0xfe);
paletteColors[1] = paletteMapper.getRGB(bytes[7681] & 0xfe);
paletteColors[2] = paletteMapper.getRGB(bytes[7682] & 0xfe);
paletteColors[3] = paletteMapper.getRGB(bytes[7683] & 0xfe);
} else {
paletteColors = PaletteUtility.getPaletteColors(
PaletteType.ATARI_DEFAULT, Palette.MULTI_1, null);
}
setImageSizeAndPalette(data, 40, 192, Palette.MULTI_MANUAL,
paletteColors);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 4);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int offset = 0;
int xpixels = 4;
for (int y1 = 0; y1 < data.getParameters().getRows(); y1++) {
for (int x1 = 0; x1 < data.getParameters().getColumns(); x1++) {
int b = data.getSourceFileByte(BIT_MAP_FILE, offset++);
if (b < 0) {
return true;
}
for (int x2 = 0; x2 < 4; x2++) {
int x = x1 * xpixels + x2;
int color = (b & mask_2bit[x2]) >>> shift_2bit[x2];
data.setPalettePixel(x, y1, color);
}
}
}
return true;
}
}

View File

@ -0,0 +1,698 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.RBGUtility;
/**
* <u>RIP picture format description</u><br/>
*
* Original text by Rocky of Madteam taken from Syzygy Magazine <br/>
* RIP picture was shown first time in Orneta of Poland in '97 in Igor demo by
* Madteam. There we copied several disks of RIP images. RIP is a new graphics
* storage format on Atari 8-bit. It is based on already famous HIP picture
* format (Gr.9 + Gr.10). Theoretically it is possible to get 144 colors (there
* are about 40 in practice) with resolution of 160x238 (RIP mode 32; 16 lum x 9
* col). RIP is more complicated than HIP, because of the header which contains
* a lot of information about colors, resolution and a note from the author. RIP
* can have various vertical sizes (max. 238 lines) which cause less space on
* disk and faster reading. <br/>
* <br/>
*
* (E.g. we have a logo with 50 lines. Our logo will be saved with 200 lines as
* HIP and takes about 16kB but saved as RIP - only 4kB plus several bytes of
* header. That's a difference, isn't it?) In addition RIP can be colored and
* HIP can only be grey scaled. (HIP can also be colored but there is no room
* for color info in the header.) The first one can still be packed (algorithm
* in end phase) for RIP dedicated Visage viewer which is able to recognize its
* size, colors, compression method and displaying on screen. Saving HIP as RIP
* is no problem 'couse of similar data format. Adapting existing HIP viewers
* for RIP pictures shouldn't be problematic too; Only what has to be done is
* format recognition, displaying of various image height and setting colors
* (for Gr.10) from the header (see below). <br/>
* <br/>
*
* <u>How to make a RIP picture?</u><br/>
*
* It can be quite difficult. There is a converter for Amiga and PC. This is not
* a real converter from any graphics format (GIF, IFF or Jpeg) to RIP. To make
* a RIP picture, you will have to use programs not only dedicated to RIP. The
* best for Amiga is Personal Paint and for PC - Display. It's quite a large
* job. One picture has to be divided into two others. Next: size modification,
* color palette reduction (one of these two pictures has to be 16 grey scales
* what can be done with almost all programs and the other picture has to be in
* 9 colors, what most programs for the Amiga and PC simply cannot do). The
* effect can be very satisfactory, but it might also be completely bad, which
* happens quite often (none of the pics is perfect). You can then always create
* a HIP picture, which is better in this case (grey scale is easier to do) but
* you will be limited to 200 lines. Well, life is brutal... <br/>
* <br/>
* <u>Header description:</u><br/>
* In 'Description' filed text with quotes (") is pure ASCII string.
*
* <pre>
* Offset | Len | Description
* --------------------------------------------
* 0 | 3 | "RIP" - RIP image identifier
* 3 | 4 | version:
* | | "1.x " - standard RIP
* | | "2.0 " - Multi RIP
* 7 | 1 | graphics mode:
* | | $20 - RIP or HIP
* | | $30 - Multi RIP, palette at the end of file
* | | $0f - Graphics 8
* | | $4f - Graphics 9
* | | $8f - Graphics 10
* | | $cf - Graphics 11
* | | $0e - Graphics 15
* 8 | 2 | compression method:
* | | 0, 0 - no compress
* | | 0, 1 - RIPPCK
* 10 | 2 | header length in bytes, MSB/LSB !!!
* 12 | 1 | not used
* 13 | 1 | image width in pixels (max. 80) *see below
* 14 | 1 | not used
* 15 | 1 | image height in lines (max. 238)
* 16 | 1 | display option (?), standard set to $20
* 17 | 1 | author note length in bytes (max. 256)
* 18 | 2 | "T:" - text identifier
* 20 | n | author note
* 20+n | 1 | number of colors (fixed = 9 from Gr.10)
* 21+n | 3 | "CM:" - color map identifier
* 24+n | 9 | color values **see below
* 33+n | 3 | "PCK" - Multi RIP packed file only, means packed
* | | images data
* </pre>
*
* Directly after header images data are stored. First Gr.10, next Gr.9.
*
* HIP and RIP are 80 pixels wide pictures with shifted 9-color plan (Gr.10)
* relativelly to 16-grey shaded plan (Gr.9) for half pixel right. Thus, they
* appear as 160x200, but one pic has only 80x200;
*
* Number of colors is fixed to 9 now but it may change. So, take number of
* colors from 20+n byte of header (n - length of author note) for safety. (RIP
* mode 48 has more colors !!)
*
* Displaying RIP "1.x" picture routine is similar to HIP routine. The only
* difference is to set color registers with values put behind "CM:" while Gr.10
* line.
*
* Information above is enough for writing own procedure showing RIP 1.x
* picture. For now I don't have any info about Multi RIP especially for
* compression algorithm and color palette. The only thing I know for sure is
* the palette should be changed every 2 scanlines. Maybe someone else knows a
* little bit more about Multi RIP (or RIP mode 48 with many more colors than
* mode 32)...
*
* Note: This implementation is based on FAIL 1.0.1 and allows 239 lines tough
* the specification above states 238 as the maximum.
*/
// TODO Verify against FAIL 1.0.2, check if the spurious grey spot and bugs are
// gone
public class LinearBitMapRIPConverter extends LinearBitMapConverter {
private final static class RIPFile {
public static final byte RIP = 0x20;
public static final byte MULTI_RIP = 0x30;
private int graphicsMode;
private int width;
private int height;
private int[] palette;
private byte[] unpackedImage;
private RIPFile(int graphicsMode, int width, int height, int[] palette,
byte[] unpacked_image) {
this.graphicsMode = graphicsMode;
this.width = width;
this.height = height;
this.palette = palette;
this.unpackedImage = unpacked_image;
}
public static RIPFile createInstance(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
if (bytes.length < 23) {
return null;
}
int graphicsMode = bytes[7];
int headerLength = (bytes[11] & 0xff) + 256 * (bytes[12] & 0xff);
int width = bytes[13] & 0xff;
int height = bytes[15] & 0xff;
int textLength = bytes[17] & 0xff;
if (bytes.length < 20 + textLength) {
return null;
}
int paletteLength = bytes[20 + textLength] & 0xff;
int dataLength = bytes.length - headerLength;
if (bytes[0] != 'R' || bytes[1] != 'I' || bytes[2] != 'P'
|| width > 80 || height > 239 || textLength > 152
|| bytes[18] != 'T' || bytes[19] != ':'
|| paletteLength != 9 || bytes[21 + textLength] != 'C'
|| bytes[22 + textLength] != 'M'
|| bytes[23 + textLength] != ':') {
return null;
}
byte[] unpackedImage = new byte[24576];
// Check compression mode.
switch (bytes[9]) {
case 0:
// No compression.
if (dataLength > unpackedImage.length) {
return null;
}
System.arraycopy(bytes, headerLength, unpackedImage, 0,
dataLength);
break;
// Compression
case 1:
if (!ShannonFano.unpack(bytes, headerLength, dataLength,
unpackedImage)) {
return null;
}
break;
default:
return null;
}
// Check graphic mode
switch (graphicsMode) {
case RIP:
break;
case MULTI_RIP:
int frame_len = (width / 2) * height;
for (int y = 0; y < height; y++) {
for (int x = 0; x < 8; x++) {
int ix = 2 * frame_len + y * 8 + x;
if (y > 0 && unpackedImage[ix] == 0)
unpackedImage[ix] = unpackedImage[ix - 8];
}
}
break;
default:
return null;
}
int[] palette = new int[paletteLength];
for (int i = 0; i < paletteLength; i++) {
palette[i] = bytes[24 + textLength + i] & 0xff;
}
RIPFile result = new RIPFile(graphicsMode, width, height, palette,
unpackedImage);
return result;
}
public int getGraphicsMode() {
return graphicsMode;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public int[] getPalette() {
return palette;
}
public byte[] getUnpackedImage() {
return unpackedImage;
}
}
private static final class ShannonFano {
private static void unpack_cnibl(byte data[], int dataOffset, int size,
int output[]) {
int x = dataOffset;
int y = 0;
while (y < size) {
int a = data[x++] & 0xff;
output[y++] = a >>> 4;
output[y++] = a & 0x0f;
}
}
private static void unpack_sort(byte data[], int dataOffset, int size,
int tre01[], int tre02[]) {
int[] pom = new int[16];
int y;
int x;
int md_ = 0;
int md = 0;
unpack_cnibl(data, dataOffset, size, tre02);
for (y = 0; y < size; y++) {
pom[tre02[y]]++;
}
x = 0;
do {
y = 0;
do {
if (x == tre02[y]) {
tre01[md_++] = y;
}
y++;
} while (y < size);
x++;
} while (x < 16);
x = 0;
do {
y = pom[x];
while (y != 0) {
tre02[md++] = x;
y--;
}
x++;
} while (x < 16);
}
private static void unpack_fano(byte data[], int dataOffset, int size,
int tre01[], int tre02[], int l0[], int h0[], int l1[],
int h1[], int lhOffset) {
int p;
int err;
int l;
int nxt;
int y;
unpack_sort(data, dataOffset, size, tre01, tre02);
clearMemory(l0, lhOffset, size);
clearMemory(l1, lhOffset, size);
clearMemory(h0, lhOffset, size);
clearMemory(h1, lhOffset, size);
p = 0;
err = 0;
l = 0;
nxt = 0;
y = 0;
do {
if (tre02[y] != 0) {
int x;
int tmp;
int val;
int a;
p += err;
x = tre02[y];
if (x != l) {
l = x;
err = 0x10000 >>> x;
}
tmp = p;
val = tre01[y];
x = tre02[y];
a = 0;
for (;;) {
int z = lhOffset + a;
x--;
tmp <<= 1;
if (tmp < 0x10000) {
if (x == 0) {
a = val;
l0[z] = a;
break;
}
a = h0[z];
if (a == 0) {
a = ++nxt;
h0[z] = a;
}
} else {
tmp &= 0xFFFF;
if (x == 0) {
a = val;
l1[z] = a;
break;
}
a = h1[z];
if (a == 0) {
a = ++nxt;
h1[z] = a;
}
}
}
}
y++;
} while (y < size);
}
private static void clearMemory(int[] array, int offset, int size) {
for (int i = 0; i < size; i++) {
array[offset + i] = 0;
}
}
public static boolean unpack(byte data[], int dataOffset,
int dataLength, byte unpackedData[]) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (dataOffset < 0) {
throw new IllegalArgumentException(
"Parameter 'dataOffset' must not be negative, specified value is "
+ dataOffset + ".");
}
if (unpackedData == null) {
throw new IllegalArgumentException(
"Parameter 'unpackedData' must not be null.");
}
int[] adl0 = new int[576];
int[] adh0 = new int[576];
int[] adl1 = new int[576];
int[] adh1 = new int[576];
int[] tre01 = new int[256];
int[] tre02 = new int[256];
int unpacked_len;
int sx, sxend;
int cx, dx;
int lic, csh, c;
// "PCK" header (16 bytes) + 288 bytes shannon-fano
if (dataLength < 16 + 288 || data[dataOffset + 0] != 'P'
|| data[dataOffset + 1] != 'C'
|| data[dataOffset + 2] != 'K') {
return false;
}
unpacked_len = (data[dataOffset + 4] & 0xff) + 256
* (data[dataOffset + 5] & 0xff) - 33;
if (unpacked_len > 0x5EFE) {
return false;
}
// Buggy pictures?!
if (unpacked_len == 16811) {
unpacked_len = 16800;
}
unpack_fano(data, dataOffset + 16, 64, tre01, tre02, adl0, adh0,
adl1, adh1, 0);
unpack_fano(data, dataOffset + 16 + 32, 256, tre01, tre02, adl0,
adh0, adl1, adh1, 64);
unpack_fano(data, dataOffset + 16 + 160, 256, tre01, tre02, adl0,
adh0, adl1, adh1, 320);
sx = dataOffset + 16 + 288;
sxend = dataOffset + dataLength + 1;
dx = 0;
lic = -1;
csh = 0;
do {
// GBIT();
if (--lic < 0) {
if (sx >= sxend) {
return false;
}
csh = data[sx++] & 0xff;
lic = 7;
}
c = (csh & (1 << lic));
if (c == 0) {
int a = 0;
for (;;) {
int y = a;
// GBIT();
if (--lic < 0) {
if (sx >= sxend) {
return false;
}
csh = data[sx++] & 0xff;
lic = 7;
}
c = (csh & (1 << lic));
if (c == 0) {
if ((a = adh0[320 + y]) == 0) {
unpackedData[dx] = (byte) adl0[320 + y];
break;
}
} else {
if ((a = adh1[320 + y]) == 0) {
unpackedData[dx] = (byte) adl1[320 + y];
break;
}
}
}
++dx;
} else {
int a = 0;
for (;;) {
int y = a;
// GBIT();
if (--lic < 0) {
if (sx >= sxend) {
return false;
}
csh = data[sx++] & 0xff;
lic = 7;
}
c = (csh & (1 << lic));
if (c == 0) {
if ((a = adh0[64 + y]) == 0) {
a = adl0[64 + y];
break;
}
} else {
if ((a = adh1[64 + y]) == 0) {
a = adl1[64 + y];
break;
}
}
}
cx = dx - (a + 2);
a = 0;
for (;;) {
int y = a;
// GBIT();
if (--lic < 0) {
if (sx >= sxend) {
return false;
}
csh = data[sx++] & 0xff;
lic = 7;
}
c = (csh & (1 << lic));
if (c == 0) {
if ((a = adh0[y]) == 0) {
a = adl0[y];
break;
}
} else {
if ((a = adh1[y]) == 0) {
a = adl1[y];
break;
}
}
}
if (cx > 0) {
System.arraycopy(unpackedData, cx, unpackedData, dx,
a + 2);
}
dx += a + 2;
}
} while (dx < unpacked_len);
return true;
}
}
public LinearBitMapRIPConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
RIPFile ripFile = RIPFile.createInstance(bytes);
if (ripFile == null) {
return false;
}
return true;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
RIPFile ripFile = RIPFile.createInstance(bytes);
if (ripFile == null) {
throw new IllegalStateException("canConvertToImage() not called");
}
int columns;
int rows;
columns = (ripFile.getWidth() + 1) / 2;
rows = ripFile.getHeight();
setImageSizeAndPalette(data, columns, rows, Palette.TRUE_COLOR, null);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 4 + 1);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int rows = data.getParameters().getRows();
int columns = data.getParameters().getColumns();
PaletteMapper paletteMapper = new Atari8BitPaletteMapper();
// Compute palette.
RIPFile ripFile = RIPFile.createInstance(data
.getSourceFileBytes(BIT_MAP_FILE));
if (ripFile == null) {
return false;
}
byte[] unpackedImage = ripFile.getUnpackedImage();
int[] graphics10Colors;
switch (ripFile.getGraphicsMode()) {
case RIPFile.RIP:
graphics10Colors = ripFile.getPalette();
break;
case RIPFile.MULTI_RIP:
graphics10Colors = new int[ripFile.getPalette().length];
break;
default:
throw new IllegalStateException("Unsupported graphics mode "
+ ripFile.getGraphicsMode() + ".");
}
// Compute the offsets in the file.
int offset9, offset10;
int frameSize = rows * columns;
offset10 = 0;
offset9 = offset10 + frameSize;
int[] buffer1 = new int[columns * 4 + 1];
int[] buffer2 = new int[columns * 4 + 1];
for (int y1 = 0; y1 < rows; y1++) {
// MultiRIP mode?
if (ripFile.getGraphicsMode() == RIPFile.MULTI_RIP) {
int offset = frameSize * 2 + ((y1 >>> 1) << 3);
for (int i = 0; i < graphics10Colors.length - 1; i++) {
graphics10Colors[i + 1] = unpackedImage[offset + i] & 0xff;
}
}
for (int x1 = 0; x1 < columns; x1++) {
if (offset9 >= unpackedImage.length) {
return true;
}
int byte9 = unpackedImage[offset9++];
if (offset10 >= unpackedImage.length) {
return true;
}
int byte10 = unpackedImage[offset10++];
// Byte 1 is the GTIA 9 byte, take the values as brightness
// values
int color1 = (byte9 & mask_4bit[0]) >>> shift_4bit[0];
int color2 = (byte9 & mask_4bit[1]) >>> shift_4bit[1];
// Byte 2 is the GTIA 10 byte, take the values from the GTIA 10
// palette
int color3 = (byte10 & mask_4bit[0]) >>> shift_4bit[0];
int color4 = (byte10 & mask_4bit[1]) >>> shift_4bit[1];
color3 = graphics10Colors[Atari8BitUtility.GRAPHICS_10_REGISTERS[color3]];
color4 = graphics10Colors[Atari8BitUtility.GRAPHICS_10_REGISTERS[color4]];
// Put the color values in the row buffer, shifted by 1 pixel
int x = x1 << 2;
buffer1[x + 0] = color1;
buffer1[x + 1] = color1;
buffer1[x + 2] = color2;
buffer1[x + 3] = color2;
buffer2[x + 1] = color3;
buffer2[x + 2] = color3;
buffer2[x + 3] = color4;
buffer2[x + 4] = color4;
}
// Merge the two buffers into combined color values.
for (int x = 0; x < buffer1.length; x++) {
int atariColor = RBGUtility.combineRGBColor(
paletteMapper.getRGBColor(buffer1[x]),
paletteMapper.getRGBColor(buffer2[x]));
data.setDirectPixel(x, y1, atariColor);
}
}
return true;
}
}

View File

@ -0,0 +1,170 @@
/**
* Copyright (C) 2009 - 2014 <a href="http://www.wudsn.com" target="_top">Peter Dell</a>
*
* This file is part of WUDSN IDE.
*
* WUDSN IDE 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.
*
* WUDSN IDE 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 WUDSN IDE. If not, see <http://www.gnu.org/licenses/>.
*/
package com.wudsn.ide.gfx.converter.atari8bit;
import com.wudsn.ide.gfx.converter.FilesConverterData;
import com.wudsn.ide.gfx.converter.ImageConverterData;
import com.wudsn.ide.gfx.converter.PaletteMapper;
import com.wudsn.ide.gfx.converter.generic.LinearBitMapConverter;
import com.wudsn.ide.gfx.model.Palette;
import com.wudsn.ide.gfx.model.RBGUtility;
/**
* Layout in the TIP picture is 9 bytes header, graphics 9 picture, graphics 10
* picture, graphics 11 picture
*/
public class LinearBitMapTIPConverter extends LinearBitMapConverter {
public LinearBitMapTIPConverter() {
}
@Override
public boolean canConvertToImage(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
if (bytes.length < 9) {
return false;
}
int frameLength = (bytes[7] & 0xff) + ((bytes[8] & 0xff) << 8);
if (bytes[0] != 'T' || bytes[1] != 'I' || bytes[2] != 'P'
|| bytes[3] != 1 || bytes[4] != 0 || bytes[5] == 0
|| (bytes[5] & 0xff) > 160 || bytes[6] == 0
|| (bytes[6] & 0xff) > 119
|| (9 + frameLength * 3) != bytes.length) {
return false;
}
return true;
}
@Override
public void convertToImageSizeAndPalette(FilesConverterData data,
byte[] bytes) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
if (bytes == null) {
throw new IllegalArgumentException(
"Parameter 'bytes' must not be null.");
}
int columns;
int rows;
columns = (bytes[5] & 0xff) / 4;
rows = (bytes[6] & 0xff);
setImageSizeAndPalette(data, columns, rows, Palette.TRUE_COLOR, null);
}
@Override
public void convertToImageDataSize(FilesConverterData data) {
data.setImageDataWidth(data.getParameters().getColumns() * 4 + 1);
data.setImageDataHeight(data.getParameters().getRows());
}
@Override
public boolean convertToImageData(FilesConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
int rows = data.getParameters().getRows();
int columns = data.getParameters().getColumns();
PaletteMapper paletteMapper=new Atari8BitPaletteMapper();
// Assume the binary is already merged in case of a 160012 bytes HIP.
int offset9, offset10, offset11;
// Assume grey scale colors by default.
int[] graphics10Colors = { 0, 0, 2, 4, 6, 8, 10, 12, 14 };
// Compute the offsets in the file.
int frameSize = rows * columns;
offset9 = 9;
offset10 = offset9 + frameSize;
offset11 = offset10 + frameSize;
int[] buffer1 = new int[columns * 4 + 1];
int[] buffer2 = new int[columns * 4 + 1];
for (int y1 = 0; y1 < rows; y1++) {
for (int x1 = 0; x1 < columns; x1++) {
int byte1 = data.getSourceFileByte(BIT_MAP_FILE, offset9++);
if (byte1 < 0) {
return true;
}
int byte2 = data.getSourceFileByte(BIT_MAP_FILE, offset10++);
if (byte2 < 0) {
return true;
}
int byte3 = data.getSourceFileByte(BIT_MAP_FILE, offset11++);
if (byte3 < 0) {
return true;
}
// Byte 1 is the GTIA 9 byte, take the values as brightness
// values
int brightness1 = (byte1 & mask_4bit[0]) >>> shift_4bit[0];
int brightness2 = (byte1 & mask_4bit[1]) >>> shift_4bit[1];
// Byte 2 is the GTIA 10 byte, take the values from the GTIA 10
// palette
int brightness3 = (byte2 & mask_4bit[0]) >>> shift_4bit[0];
int brightness4 = (byte2 & mask_4bit[1]) >>> shift_4bit[1];
brightness3 = graphics10Colors[Atari8BitUtility.GRAPHICS_10_REGISTERS[brightness3]];
brightness4 = graphics10Colors[Atari8BitUtility.GRAPHICS_10_REGISTERS[brightness4]];
// Byte 3 is the GTIA 11 byte, take the values as color values
int color1 = (byte3 & 0xf0);
int color2 = (byte3 & 0x0f) << 4;
// Put the color values in the row buffer, shifted by 1 pixel
int x = x1 << 2;
buffer1[x + 0] = color1 | brightness1;
buffer1[x + 1] = color1 | brightness1;
buffer1[x + 2] = color2 | brightness2;
buffer1[x + 3] = color2 | brightness2;
buffer2[x + 1] = color1 | brightness3;
buffer2[x + 2] = color1 | brightness3;
buffer2[x + 3] = color2 | brightness4;
buffer2[x + 4] = color2 | brightness4;
}
// Merge the two buffers into combined color values.
for (int x = 0; x < buffer1.length; x++) {
int atariColor = RBGUtility.combineRGBColor(
paletteMapper.getRGBColor(buffer1[x]),
paletteMapper.getRGBColor(buffer2[x]));
data.setDirectPixel(x, y1, atariColor);
}
}
return true;
}
public static void convertToFileData(ImageConverterData data) {
if (data == null) {
throw new IllegalArgumentException(
"Parameter 'data' must not be null.");
}
}
}

Some files were not shown because too many files have changed in this diff Show More