Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
saharNooby committed Dec 2, 2021
0 parents commit 9d6c3fc
Show file tree
Hide file tree
Showing 12 changed files with 921 additions and 0 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 saharNooby (https://github.com/saharNooby)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# qoi-java

A pure Java 8 implementation of [Quite OK Image Format](https://github.com/phoboslab/qoi).

This library has no runtime dependencies, including Java AWT. `BufferedImage` support is provided using separate module [qoi-java-awt](https://github.com/saharNooby/qoi-java-awt).

**Production use warning**: QOI file format is not finalized yet. You can track progress [here in the original repository](https://github.com/phoboslab/qoi/issues/48).

## How to Use

### Build and Install

You will need Git, Maven and JDK 8 or higher.

```shell
git clone https://github.com/saharNooby/qoi-java.git
cd qoi-java
mvn clean install
```

Add this library as a dependency to your build system. Maven example:

```xml
<dependency>
<groupId>me.saharnooby</groupId>
<artifactId>qoi-java</artifactId>
<version>0.0.1</version>
</dependency>
```

### Usage

Use methods in class `me.saharnooby.qoi.QOIUtil`.

Usage example:

```java
// Read image from a file
QOIImage image = QOIUtil.readFile(new File("image.qoi"));

System.out.println("Image size: " + image.getWidth() + " x " + image.getHeight());

// Access pixel data
System.out.println("Red channel is " + image.getPixelData()[0]);

// Create new 1x1 RGBA image from raw pixel data
byte[] pixelData = {(byte) 255, 127, 0, (byte) 255};

QOIImage orangeImage = QOIUtil.createFromPixelData(pixelData, 1, 1, 4);

// Write image to a file
QOIUtil.writeImage(orangeImage, new File("orange.qoi"));
```

### Use with `BufferedImage`

To convert QOI images to BufferedImages and back, you need to also add [qoi-java-awt](https://github.com/saharNooby/qoi-java-awt) dependency.

Use methods in class `me.saharnooby.qoi.QOIUtilAWT`.

Usage example:

```java
// Convert PNG to QOI
BufferedImage image = ImageIO.read(new File("image.png"));
QOIImage qoi = QOIUtilAWT.createFromBufferedImage(image);
QOIUtil.writeImage(qoi, new File("image.qoi"));

// Convert QOI to PNG
QOIImage secondImage = QOIUtil.readFile(new File("second-image.qoi"));
BufferedImage convertedImage = QOIUtilAWT.convertToBufferedImage(secondImage);
ImageIO.write(convertedImage, "PNG", new File("second-image.png"));
```

## Compatibility

No AWT classes are used, so it should be compatible with Android. Please report compatibility issues, if they arise.

## Versioning

This project uses semantic versioning. Until QOI file format is finalized, major version will remain 0.
96 changes: 96 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>me.saharnooby</groupId>
<artifactId>qoi-java</artifactId>
<version>0.0.1</version>

<name>qoi-java</name>
<description>A pure Java 8 implementation of Quite OK Image Format</description>
<url>https://github.com/saharNooby/qoi-java</url>

<licenses>
<license>
<name>MIT License</name>
<url>http://www.opensource.org/licenses/mit-license.php</url>
</license>
</licenses>

<developers>
<developer>
<name>saharNooby</name>
<url>https://saharnooby.me</url>
</developer>
</developers>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.0.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<defaultGoal>clean install</defaultGoal>

<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
16 changes: 16 additions & 0 deletions src/main/java/me/saharnooby/qoi/InvalidQOIStreamException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package me.saharnooby.qoi;

import lombok.NonNull;

import java.io.IOException;

/**
* This exception is thrown when decoder detects invalid data in the input stream.
*/
public final class InvalidQOIStreamException extends IOException {

InvalidQOIStreamException(@NonNull String message) {
super(message);
}

}
47 changes: 47 additions & 0 deletions src/main/java/me/saharnooby/qoi/QOICodec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package me.saharnooby.qoi;

/**
* Contains constants and utility methods for decoder and encoder.
*/
final class QOICodec {

static final int QOI_SRGB = 0x00;
static final int QOI_SRGB_LINEAR_ALPHA = 0x01;
static final int QOI_LINEAR = 0x0F;

static final int QOI_INDEX = 0x00;
static final int QOI_RUN_8 = 0x40;
static final int QOI_RUN_16 = 0x60;
static final int QOI_DIFF_8 = 0x80;
static final int QOI_DIFF_16 = 0xC0;
static final int QOI_DIFF_24 = 0xE0;
static final int QOI_COLOR = 0xF0;

static final int QOI_MASK_2 = 0xC0;
static final int QOI_MASK_3 = 0xE0;
static final int QOI_MASK_4 = 0xF0;

static final int QOI_MAGIC = 'q' << 24 | 'o' << 16 | 'i' << 8 | 'f';

static final int QOI_PADDING = 4;

private static final int HASH_TABLE_SIZE = 64;

static byte[] createHashTable() {
byte[] index = new byte[HASH_TABLE_SIZE * 4];

// Fill alpha with default value of 255
for (int i = 3; i < index.length; i += 4) {
index[i] = (byte) 0xFF;
}

return index;
}

static int getHashTableIndex(int r, int g, int b, int a) {
int hash = r ^ g ^ b ^ a;

return hash & (HASH_TABLE_SIZE - 1);
}

}
21 changes: 21 additions & 0 deletions src/main/java/me/saharnooby/qoi/QOIColorSpace.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package me.saharnooby.qoi;

/**
* A color space that can be specified in a QOI file.
*/
public enum QOIColorSpace {

/**
* sRGB color space.
*/
SRGB,
/**
* sRGB color space with linear alpha channel.
*/
SRGB_LINEAR_ALPHA,
/**
* All channels are linear.
*/
LINEAR

}

0 comments on commit 9d6c3fc

Please sign in to comment.