|
@@ -27,7 +27,6 @@ import "core:time"
|
|
|
|
|
|
import "core:runtime"
|
|
|
|
|
|
-WRITE_PPM_ON_FAIL :: #config(WRITE_PPM_ON_FAIL, false)
|
|
|
TEST_SUITE_PATH :: "assets/PNG"
|
|
|
|
|
|
TEST_count := 0
|
|
@@ -1879,12 +1878,6 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if WRITE_PPM_ON_FAIL && !passed && err == nil { // It loaded but had an error in its compares.
|
|
|
- testing.logf(t, "Test failed, writing ppm/%v-%v.ppm to help debug.\n", file.file, count)
|
|
|
- output := fmt.tprintf("ppm/%v-%v.ppm", file.file, count)
|
|
|
- write_image_as_ppm(output, img)
|
|
|
- }
|
|
|
-
|
|
|
png.destroy(img)
|
|
|
|
|
|
for _, v in track.allocation_map {
|
|
@@ -1895,198 +1888,4 @@ run_png_suite :: proc(t: ^testing.T, suite: []PNG_Test) -> (subtotal: int) {
|
|
|
}
|
|
|
|
|
|
return
|
|
|
-}
|
|
|
-
|
|
|
-// Crappy PPM writer used during testing. Don't use in production.
|
|
|
-write_image_as_ppm :: proc(filename: string, image: ^image.Image) -> (success: bool) {
|
|
|
-
|
|
|
- _bg :: proc(x, y: int, high := true) -> (res: [3]u16) {
|
|
|
- if high {
|
|
|
- l := u16(30 * 256 + 30)
|
|
|
-
|
|
|
- if (x & 4 == 0) ~ (y & 4 == 0) {
|
|
|
- res = [3]u16{l, l, l}
|
|
|
- } else {
|
|
|
- res = [3]u16{l >> 1, l >> 1, l >> 1}
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (x & 4 == 0) ~ (y & 4 == 0) {
|
|
|
- res = [3]u16{30, 30, 30}
|
|
|
- } else {
|
|
|
- res = [3]u16{15, 15, 15}
|
|
|
- }
|
|
|
- }
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- using image
|
|
|
- using os
|
|
|
-
|
|
|
- flags: int = O_WRONLY|O_CREATE|O_TRUNC
|
|
|
-
|
|
|
- img := image
|
|
|
-
|
|
|
- // PBM 16-bit images are big endian
|
|
|
- when ODIN_ENDIAN == .Little {
|
|
|
- if img.depth == 16 {
|
|
|
- // The pixel components are in Big Endian. Let's byteswap back.
|
|
|
- input := mem.slice_data_cast([]u16, img.pixels.buf[:])
|
|
|
- output := mem.slice_data_cast([]u16be, img.pixels.buf[:])
|
|
|
- #no_bounds_check for v, i in input {
|
|
|
- output[i] = u16be(v)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- pix := bytes.buffer_to_bytes(&img.pixels)
|
|
|
-
|
|
|
- if len(pix) == 0 || len(pix) < image.width * image.height * int(image.channels) {
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- mode: int = 0
|
|
|
- when ODIN_OS == .Linux || ODIN_OS == .Darwin {
|
|
|
- // NOTE(justasd): 644 (owner read, write; group read; others read)
|
|
|
- mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
|
|
|
- }
|
|
|
-
|
|
|
- fd, err := open(filename, flags, mode)
|
|
|
- if err != 0 {
|
|
|
- return false
|
|
|
- }
|
|
|
- defer close(fd)
|
|
|
-
|
|
|
- write_string(fd,
|
|
|
- fmt.tprintf("P6\n%v %v\n%v\n", width, height, (1 << uint(depth) -1)),
|
|
|
- )
|
|
|
-
|
|
|
- if channels == 3 {
|
|
|
- // We don't handle transparency here...
|
|
|
- write_ptr(fd, raw_data(pix), len(pix))
|
|
|
- } else {
|
|
|
- bpp := depth == 16 ? 2 : 1
|
|
|
- bytes_needed := width * height * 3 * bpp
|
|
|
-
|
|
|
- op := bytes.Buffer{}
|
|
|
- bytes.buffer_init_allocator(&op, bytes_needed, bytes_needed)
|
|
|
- defer bytes.buffer_destroy(&op)
|
|
|
-
|
|
|
- if channels == 1 {
|
|
|
- if depth == 16 {
|
|
|
- assert(len(pix) == width * height * 2)
|
|
|
- p16 := mem.slice_data_cast([]u16, pix)
|
|
|
- o16 := mem.slice_data_cast([]u16, op.buf[:])
|
|
|
- #no_bounds_check for len(p16) != 0 {
|
|
|
- r := u16(p16[0])
|
|
|
- o16[0] = r
|
|
|
- o16[1] = r
|
|
|
- o16[2] = r
|
|
|
- p16 = p16[1:]
|
|
|
- o16 = o16[3:]
|
|
|
- }
|
|
|
- } else {
|
|
|
- o := 0
|
|
|
- for i := 0; i < len(pix); i += 1 {
|
|
|
- r := pix[i]
|
|
|
- op.buf[o ] = r
|
|
|
- op.buf[o+1] = r
|
|
|
- op.buf[o+2] = r
|
|
|
- o += 3
|
|
|
- }
|
|
|
- }
|
|
|
- write_ptr(fd, raw_data(op.buf), len(op.buf))
|
|
|
- } else if channels == 2 {
|
|
|
- if depth == 16 {
|
|
|
- p16 := mem.slice_data_cast([]u16, pix)
|
|
|
- o16 := mem.slice_data_cast([]u16, op.buf[:])
|
|
|
-
|
|
|
- bgcol := img.background
|
|
|
-
|
|
|
- #no_bounds_check for len(p16) != 0 {
|
|
|
- r := f64(u16(p16[0]))
|
|
|
- bg: f64
|
|
|
- if bgcol != nil {
|
|
|
- v := bgcol.([3]u16)[0]
|
|
|
- bg = f64(v)
|
|
|
- }
|
|
|
- a := f64(u16(p16[1])) / 65535.0
|
|
|
- l := (a * r) + (1 / a) * bg
|
|
|
-
|
|
|
- o16[0] = u16(l)
|
|
|
- o16[1] = u16(l)
|
|
|
- o16[2] = u16(l)
|
|
|
-
|
|
|
- p16 = p16[2:]
|
|
|
- o16 = o16[3:]
|
|
|
- }
|
|
|
- } else {
|
|
|
- o := 0
|
|
|
- for i := 0; i < len(pix); i += 2 {
|
|
|
- r := pix[i]; a := pix[i+1]; a1 := f32(a) / 255.0
|
|
|
- c := u8(f32(r) * a1)
|
|
|
- op.buf[o ] = c
|
|
|
- op.buf[o+1] = c
|
|
|
- op.buf[o+2] = c
|
|
|
- o += 3
|
|
|
- }
|
|
|
- }
|
|
|
- write_ptr(fd, raw_data(op.buf), len(op.buf))
|
|
|
- } else if channels == 4 {
|
|
|
- if depth == 16 {
|
|
|
- p16 := mem.slice_data_cast([]u16be, pix)
|
|
|
- o16 := mem.slice_data_cast([]u16be, op.buf[:])
|
|
|
-
|
|
|
- i := 0
|
|
|
- for len(p16) > 0 {
|
|
|
- i += 1
|
|
|
- x := i % width
|
|
|
- y := i / width
|
|
|
- bg := _bg(x, y, true)
|
|
|
-
|
|
|
- r := f32(p16[0])
|
|
|
- g := f32(p16[1])
|
|
|
- b := f32(p16[2])
|
|
|
- a := f32(p16[3]) / 65535.0
|
|
|
-
|
|
|
- lr := (a * r) + (1 / a) * f32(bg[0])
|
|
|
- lg := (a * g) + (1 / a) * f32(bg[1])
|
|
|
- lb := (a * b) + (1 / a) * f32(bg[2])
|
|
|
-
|
|
|
- o16[0] = u16be(lr)
|
|
|
- o16[1] = u16be(lg)
|
|
|
- o16[2] = u16be(lb)
|
|
|
-
|
|
|
- p16 = p16[4:]
|
|
|
- o16 = o16[3:]
|
|
|
- }
|
|
|
- } else {
|
|
|
- o := 0
|
|
|
-
|
|
|
- for i := 0; i < len(pix); i += 4 {
|
|
|
-
|
|
|
- x := (i / 4) % width
|
|
|
- y := i / width / 4
|
|
|
- _b := _bg(x, y, false)
|
|
|
- bgcol := [3]u8{u8(_b[0]), u8(_b[1]), u8(_b[2])}
|
|
|
-
|
|
|
- r := f32(pix[i])
|
|
|
- g := f32(pix[i+1])
|
|
|
- b := f32(pix[i+2])
|
|
|
- a := f32(pix[i+3]) / 255.0
|
|
|
-
|
|
|
- lr := u8(f32(r) * a + (1 / a) * f32(bgcol[0]))
|
|
|
- lg := u8(f32(g) * a + (1 / a) * f32(bgcol[1]))
|
|
|
- lb := u8(f32(b) * a + (1 / a) * f32(bgcol[2]))
|
|
|
- op.buf[o ] = lr
|
|
|
- op.buf[o+1] = lg
|
|
|
- op.buf[o+2] = lb
|
|
|
- o += 3
|
|
|
- }
|
|
|
- }
|
|
|
- write_ptr(fd, raw_data(op.buf), len(op.buf))
|
|
|
- } else {
|
|
|
- return false
|
|
|
- }
|
|
|
- }
|
|
|
- return true
|
|
|
}
|