Mercurial > games > semicongine
comparison semiconginev2/image.nim @ 1242:e8b3dc80e48e
add: PNG loading and tests for it
author | sam <sam@basx.dev> |
---|---|
date | Mon, 22 Jul 2024 15:53:32 +0700 |
parents | |
children | c15770761865 |
comparison
equal
deleted
inserted
replaced
1241:a0ed1a918fda | 1242:e8b3dc80e48e |
---|---|
1 type | |
2 Gray* = TVec1[uint8] | |
3 RGBA* = TVec4[uint8] | |
4 PixelType* = Gray | RGBA | |
5 Image*[T: PixelType] = object | |
6 width*: uint32 | |
7 height*: uint32 | |
8 interpolation*: VkFilter = VK_FILTER_LINEAR | |
9 data*: seq[T] | |
10 vk*: VkImage | |
11 imageview*: VkImageView | |
12 sampler*: VkSampler | |
13 isRenderTarget*: bool = false | |
14 samples*: VkSampleCountFlagBits = VK_SAMPLE_COUNT_1_BIT | |
15 | |
16 proc LoadImage*[T: PixelType](path: string, package = DEFAULT_PACKAGE): Image[T] = | |
17 assert path.splitFile().ext.toLowerAscii == ".png" | |
18 when T is Gray: | |
19 let pngType = 0.cint | |
20 elif T is RGBA: | |
21 let pngType = 6.cint | |
22 | |
23 let indata = loadResource_intern(path, package = package).readAll() | |
24 var w, h: cuint | |
25 var data: cstring | |
26 | |
27 if lodepng_decode_memory(out_data = addr(data), w = addr(w), h = addr(h), in_data = cstring(indata), insize = csize_t(indata.len), colorType = pngType, bitdepth = 8) != 0: | |
28 raise newException(Exception, "An error occured while loading PNG file") | |
29 | |
30 let imagesize = w * h * 4 | |
31 result = Image[T](width: w, height: h, data: newSeq[T](w * h)) | |
32 copyMem(result.data.ToCPointer, data, imagesize) | |
33 nativeFree(data) | |
34 | |
35 when T is RGBA: # converkt to BGRA | |
36 for i in 0 ..< result.data.len: | |
37 swap(result.data[i][0], result.data[i][2]) | |
38 | |
39 proc toPNG[T: PixelType](image: Image[T]): seq[uint8] = | |
40 when T is Gray: | |
41 let pngType = 0 # hardcoded in lodepng.h | |
42 else: | |
43 let pngType = 6 # hardcoded in lodepng.h | |
44 var | |
45 pngData: cstring | |
46 pngSize: csize_t | |
47 for y in 0 ..< image.height: | |
48 for x in 0 ..< image.width: | |
49 discard | |
50 let ret = lodepng_encode_memory( | |
51 addr pngData, | |
52 addr pngSize, | |
53 cast[cstring](image.imagedata.ToCPointer), | |
54 cuint(image.width), | |
55 cuint(image.height), | |
56 cint(pngType), | |
57 8, | |
58 ) | |
59 assert ret == 0, &"There was an error with generating the PNG data for image {image}, result was: {ret}" | |
60 result = newSeq[uint8](pngSize) | |
61 for i in 0 ..< pngSize: | |
62 result[i] = uint8(pngData[i]) | |
63 nativeFree(pngData) | |
64 | |
65 proc WritePNG*(image: Image, filename: string) = | |
66 let f = filename.open(mode = fmWrite) | |
67 let data = image.toPNG() | |
68 let written = f.writeBytes(data, 0, data.len) | |
69 assert written == data.len, &"There was an error while saving '{filename}': only {written} of {data.len} bytes were written" | |
70 f.close() |