mirror of
https://github.com/ollama/ollama.git
synced 2025-05-17 06:55:09 +02:00
387 lines
9.6 KiB
Go
387 lines
9.6 KiB
Go
package mllama
|
|
|
|
import (
|
|
"image"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
)
|
|
|
|
func TestSupportedAspectRatios(t *testing.T) {
|
|
cases := []struct {
|
|
p ImageProcessor
|
|
want []supportedAspectRatio
|
|
}{
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 1},
|
|
want: []supportedAspectRatio{
|
|
{1, 1, 1},
|
|
},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 2},
|
|
want: []supportedAspectRatio{
|
|
{1, 1, 1},
|
|
{2, 1, 2},
|
|
{3, 2, 1},
|
|
},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 3},
|
|
want: []supportedAspectRatio{
|
|
{1, 1, 1},
|
|
{2, 1, 2},
|
|
{3, 1, 3},
|
|
{4, 2, 1},
|
|
{5, 3, 1},
|
|
},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4},
|
|
want: []supportedAspectRatio{
|
|
{1, 1, 1},
|
|
{2, 1, 2},
|
|
{3, 1, 3},
|
|
{4, 1, 4},
|
|
{5, 2, 1},
|
|
{6, 2, 2},
|
|
{7, 3, 1},
|
|
{8, 4, 1},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range cases {
|
|
actual := tt.p.supportedAspectRatios()
|
|
if diff := cmp.Diff(actual, tt.want, cmp.AllowUnexported(supportedAspectRatio{})); diff != "" {
|
|
t.Errorf("mismatch (-got +want):\n%s", diff)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestFitToCanvas(t *testing.T) {
|
|
cases := []struct {
|
|
p ImageProcessor
|
|
image image.Point
|
|
canvas image.Point
|
|
expect image.Point
|
|
}{
|
|
{
|
|
p: ImageProcessor{imageSize: 200},
|
|
image: image.Point{400, 400},
|
|
canvas: image.Point{640, 480},
|
|
expect: image.Point{400, 400},
|
|
},
|
|
{
|
|
p: ImageProcessor{imageSize: 200},
|
|
image: image.Point{1024, 768},
|
|
canvas: image.Point{640, 480},
|
|
expect: image.Point{640, 480},
|
|
},
|
|
{
|
|
p: ImageProcessor{imageSize: 750},
|
|
image: image.Point{500, 500},
|
|
canvas: image.Point{1000, 1000},
|
|
expect: image.Point{750, 750},
|
|
},
|
|
{
|
|
p: ImageProcessor{imageSize: 2000},
|
|
image: image.Point{500, 1000},
|
|
canvas: image.Point{2000, 2000},
|
|
expect: image.Point{1000, 2000},
|
|
},
|
|
{
|
|
p: ImageProcessor{imageSize: 1000},
|
|
image: image.Point{4000, 3000},
|
|
canvas: image.Point{2000, 1000},
|
|
expect: image.Point{1333, 1000},
|
|
},
|
|
{
|
|
p: ImageProcessor{imageSize: 560},
|
|
image: image.Point{667, 1000},
|
|
canvas: image.Point{1000, 1000},
|
|
expect: image.Point{667, 1000},
|
|
},
|
|
}
|
|
|
|
for _, tt := range cases {
|
|
actual := tt.p.fitToCanvas(tt.image, tt.canvas)
|
|
if diff := cmp.Diff(actual, tt.expect); diff != "" {
|
|
t.Errorf("mismatch (-got +want):\n%s", diff)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestOptimalTiledCanvas(t *testing.T) {
|
|
cases := []struct {
|
|
p ImageProcessor
|
|
image image.Point
|
|
expect image.Point
|
|
}{
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 1000},
|
|
image: image.Point{1024, 768},
|
|
expect: image.Point{2000, 1000},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{1024, 768},
|
|
expect: image.Point{1120, 1120},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{800, 600},
|
|
expect: image.Point{1120, 1120},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{640, 480},
|
|
expect: image.Point{1120, 560},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{320, 200},
|
|
expect: image.Point{560, 560},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{1320, 200},
|
|
expect: image.Point{1680, 560},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{2000, 200},
|
|
expect: image.Point{2240, 560},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{10000, 200},
|
|
expect: image.Point{2240, 560},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{480, 640},
|
|
expect: image.Point{560, 1120},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{200, 320},
|
|
expect: image.Point{560, 560},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{200, 1320},
|
|
expect: image.Point{560, 1680},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{200, 2000},
|
|
expect: image.Point{560, 2240},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{200, 10000},
|
|
expect: image.Point{560, 2240},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
image: image.Point{10000, 10000},
|
|
expect: image.Point{1120, 1120},
|
|
},
|
|
}
|
|
|
|
for _, tt := range cases {
|
|
actual := tt.p.optimalTiledCanvas(tt.image)
|
|
if diff := cmp.Diff(actual, tt.expect); diff != "" {
|
|
t.Errorf("mismatch (-got +want):\n%s", diff)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSplitToTiles(t *testing.T) {
|
|
cases := []struct {
|
|
imageMax image.Point
|
|
numTiles image.Point
|
|
expect []image.Image
|
|
}{
|
|
{
|
|
imageMax: image.Point{1024, 768},
|
|
numTiles: image.Point{1, 1},
|
|
expect: []image.Image{image.NewRGBA(image.Rect(0, 0, 1024, 768))},
|
|
},
|
|
{
|
|
imageMax: image.Point{1000, 500},
|
|
numTiles: image.Point{2, 1},
|
|
expect: []image.Image{
|
|
image.NewRGBA(image.Rect(0, 0, 500, 500)),
|
|
image.NewRGBA(image.Rect(500, 0, 1000, 500)),
|
|
},
|
|
},
|
|
{
|
|
imageMax: image.Point{1000, 1000},
|
|
numTiles: image.Point{2, 2},
|
|
expect: []image.Image{
|
|
image.NewRGBA(image.Rect(0, 0, 500, 500)),
|
|
image.NewRGBA(image.Rect(500, 0, 1000, 500)),
|
|
image.NewRGBA(image.Rect(0, 500, 500, 1000)),
|
|
image.NewRGBA(image.Rect(500, 500, 1000, 1000)),
|
|
},
|
|
},
|
|
}
|
|
|
|
var p ImageProcessor
|
|
|
|
for _, tt := range cases {
|
|
actual := p.splitToTiles(image.NewRGBA(image.Rectangle{Max: tt.imageMax}), tt.numTiles)
|
|
|
|
if len(actual) != len(tt.expect) {
|
|
t.Errorf("incorrect number of images '%d': expect: '%d'", len(actual), len(tt.expect))
|
|
}
|
|
|
|
for i := range actual {
|
|
if actual[i].Bounds() != tt.expect[i].Bounds() {
|
|
t.Errorf("image size incorrect: '%#v': expect: '%#v'", actual[i].Bounds(), tt.expect[i].Bounds())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestResize(t *testing.T) {
|
|
cases := []struct {
|
|
p ImageProcessor
|
|
imageMax image.Point
|
|
expectImage image.Image
|
|
expectAspectRatio image.Point
|
|
}{
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 1, imageSize: 100},
|
|
imageMax: image.Point{200, 200},
|
|
expectImage: image.NewRGBA(image.Rect(0, 0, 100, 100)),
|
|
expectAspectRatio: image.Point{1, 1},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 2, imageSize: 100},
|
|
imageMax: image.Point{200, 200},
|
|
expectImage: image.NewRGBA(image.Rect(0, 0, 100, 100)),
|
|
expectAspectRatio: image.Point{1, 1},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
imageMax: image.Point{10, 10},
|
|
expectImage: image.NewRGBA(image.Rect(0, 0, 560, 560)),
|
|
expectAspectRatio: image.Point{1, 1},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
imageMax: image.Point{2560, 1920},
|
|
expectImage: image.NewRGBA(image.Rect(0, 0, 1120, 840)),
|
|
expectAspectRatio: image.Point{2, 2},
|
|
},
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
imageMax: image.Point{1024, 768},
|
|
expectImage: image.NewRGBA(image.Rect(0, 0, 1024, 768)),
|
|
expectAspectRatio: image.Point{2, 2},
|
|
},
|
|
}
|
|
|
|
for _, tt := range cases {
|
|
actualImage, actualAspectRatio := tt.p.resize(image.Rectangle{Max: tt.imageMax})
|
|
|
|
if actualImage.Bounds() != tt.expectImage.Bounds() {
|
|
t.Errorf("image size incorrect: '%#v': expect: '%#v'", actualImage.Bounds(), tt.expectImage.Bounds())
|
|
}
|
|
|
|
if actualAspectRatio != tt.expectAspectRatio {
|
|
t.Errorf("aspect ratio incorrect: '%#v': expect: '%#v'", actualAspectRatio, tt.expectAspectRatio)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPad(t *testing.T) {
|
|
cases := []struct {
|
|
p ImageProcessor
|
|
imageMax image.Point
|
|
aspectRatio image.Point
|
|
expect image.Image
|
|
}{
|
|
{
|
|
p: ImageProcessor{maxNumTiles: 4, imageSize: 560},
|
|
imageMax: image.Point{1000, 667},
|
|
aspectRatio: image.Point{2, 2},
|
|
expect: image.NewRGBA(image.Rect(0, 0, 1120, 1120)),
|
|
},
|
|
}
|
|
|
|
for _, tt := range cases {
|
|
actual := tt.p.pad(image.Rectangle{Max: tt.imageMax}, tt.aspectRatio)
|
|
|
|
if actual.Bounds() != tt.expect.Bounds() {
|
|
t.Errorf("image size incorrect: '%#v': expect: '%#v'", actual.Bounds(), tt.expect.Bounds())
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPackImages(t *testing.T) {
|
|
cases := []struct {
|
|
imageMax image.Point
|
|
aspectRatio image.Point
|
|
expectVals int
|
|
}{
|
|
{
|
|
imageMax: image.Point{1120, 1120},
|
|
aspectRatio: image.Point{2, 2},
|
|
expectVals: 2 * 2 * 3 * 560 * 560,
|
|
},
|
|
{
|
|
imageMax: image.Point{560, 560},
|
|
aspectRatio: image.Point{1, 1},
|
|
expectVals: 1 * 1 * 3 * 560 * 560,
|
|
},
|
|
{
|
|
imageMax: image.Point{1120, 560},
|
|
aspectRatio: image.Point{1, 2},
|
|
expectVals: 1 * 2 * 3 * 560 * 560,
|
|
},
|
|
}
|
|
|
|
for _, tt := range cases {
|
|
var p ImageProcessor
|
|
actualVals := p.pack(image.NewRGBA(image.Rectangle{Max: tt.imageMax}), tt.aspectRatio)
|
|
if len(actualVals) != tt.expectVals {
|
|
t.Errorf("packed image size incorrect: '%d': expect: '%d'", len(actualVals), tt.expectVals)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPreprocess(t *testing.T) {
|
|
cases := []struct {
|
|
imageMax image.Point
|
|
expectAspectRatioID int
|
|
}{
|
|
{
|
|
imageMax: image.Point{10, 10},
|
|
expectAspectRatioID: 1,
|
|
},
|
|
{
|
|
imageMax: image.Point{1024, 768},
|
|
expectAspectRatioID: 6,
|
|
},
|
|
}
|
|
|
|
p := ImageProcessor{imageSize: 560, maxNumTiles: 4}
|
|
for _, tt := range cases {
|
|
img, aspectRatio, err := p.ProcessImage(image.NewRGBA(image.Rectangle{Max: tt.imageMax}))
|
|
if err != nil {
|
|
t.Fatalf("error processing: %q", err)
|
|
}
|
|
|
|
if len(img) == 0 {
|
|
t.Errorf("no image data returned")
|
|
}
|
|
|
|
if aspectRatio.rank != tt.expectAspectRatioID {
|
|
t.Errorf("aspect ratio incorrect: '%d': expect: '%d'", aspectRatio, tt.expectAspectRatioID)
|
|
}
|
|
}
|
|
}
|