Color quantization: Difference between revisions

Improved names in second D entry
(Updated second D entry)
(Improved names in second D entry)
Line 288:
import std.exception: enforce;
import std.array: empty;
import std.compiler: version_minor;
 
enum ON_INHEAP = 1;
Line 324 ⟶ 323:
} while (line.length && line[0] == '#');
 
immutableconst size = line.split.to!(uint[2]);
static if (version_minor < 66) { //*
const enforce(size.length == line.split.to!(uint[]2);
//immutable enforce(size.length == line.split.to!(uint[2]);
} else {
immutable size = line.split.to!(uint[2]);
}
auto img = imageNew(size[0], size[1]);
enforce(fIn.readln.strip == "255");
Line 355 ⟶ 351:
}
 
struct NodeHeapHeapNode {
uint alloc, n;
OctreeNode** buf;
}
 
int cmpNodecmpOctreeNode(in OctreeNode* a, in OctreeNode* b) pure nothrow @safe @nogc
pure nothrow @safe @nogc
in {
assert(a != null);
assert(b != null);
} out(result) {
assert(result == 0-1 || result == 10 || result == -1);
} body {
if (a.nKids < b.nKids)
Line 377 ⟶ 374:
}
 
void downHeap(NodeHeapHeapNode* h, OctreeNode* p) pure nothrow @nogc
in {
assert(h != null);
Line 388 ⟶ 385:
if (m >= h.n)
break;
if (m + 1 < h.n && cmpNodecmpOctreeNode(h.buf[m], h.buf[m + 1]) > 0)
m++;
 
if (cmpNodecmpOctreeNode(p, h.buf[m]) <= 0)
break;
 
Line 403 ⟶ 400:
}
 
void upHeap(NodeHeapHeapNode* h, OctreeNode* p) pure nothrow @nogc
in {
assert(h != null);
Line 412 ⟶ 409:
while (n > 1) {
auto prev = h.buf[n / 2];
if (cmpNodecmpOctreeNode(p, prev) >= 0)
break;
 
Line 424 ⟶ 421:
}
 
void heapAddaddHeap(NodeHeapHeapNode* h, OctreeNode* p) nothrow @nogc
in {
assert(h != null);
Line 450 ⟶ 447:
}
 
OctreeNode* popHeap(NodeHeapHeapNode* h) pure nothrow @nogc
in {
assert(h != null);
Line 470 ⟶ 467:
}
 
OctreeNode* nodeNewoctreeNodeNew(in ubyte idx, in ubyte depth, OctreeNode* p,
ref OctreeNode[] pool) nothrow @nogc
out(result) {
assert(result != null);
Line 494 ⟶ 491:
}
 
void nodeFreeoctreeNodeFree(ref OctreeNode[] poolArrpool) nothrow @nogc
out {
assert(poolArrpool.length == 0empty);
} body {
auto poolpoolPtr = poolArrpool.ptr;
 
while (poolpoolPtr) {
auto p = poolpoolPtr.parent;
free(poolpoolPtr);
poolpoolPtr = p;
}
 
poolArrpool = null;
}
 
OctreeNode* nodeInsertoctreeNodeInsert(OctreeNode* root, in ubyte* pix, ref OctreeNode[] pool)
nothrow @nogc
in {
assert(root != null);
assert(pix != null);
assert(!pool.length != 0empty);
} out(result) {
assert(result != null);
Line 525 ⟶ 522:
!!(pix[2] & bit);
if (!root.kids[i])
root.kids[i] = nodeNewoctreeNodeNew(i, depth, root, pool);
 
root = root.kids[i];
Line 537 ⟶ 534:
}
 
OctreeNode* nodeFoldoctreeNodeFold(OctreeNode* p) nothrow @nogc
in {
assert(p != null);
Line 575 ⟶ 572:
}
 
void errorDiffuse(Image* im, NodeHeapHeapNode* h) nothrow @nogc
in {
assert(im != null);
Line 686 ⟶ 683:
} body {
auto pix = im.pix.ptr;
NodeHeapHeapNode heap = { 0, 0, null };
OctreeNode[] pool;
 
auto root = nodeNewoctreeNodeNew(0, 0, null, pool);
for (uint i = 0; i < im.w * im.h; i++, pix += 3)
heapAddaddHeap(&heap, nodeInsertoctreeNodeInsert(root, pix, pool));
 
while (heap.n > nColors + 1)
heapAddaddHeap(&heap, nodeFoldoctreeNodeFold(popHeap(&heap)));
 
foreach (immutable i; 1 .. heap.n) {
Line 712 ⟶ 709:
}
 
pool.nodeFreeoctreeNodeFree;
heap.buf.free;
}