STUDIO HAZE · image
Topaz source
Open by house policy. Topaz is our own language.
Topaz 5.9 · 42 files
topaz/src/render.tpz
Topaz · 11664 B · Original file
1
// Canonical raster and PNG rendering.3
import std.bytes { Bytes }4
import std.hash5
import plan { 보호길이, 프로필해시, 픽셀글꼴 }6
import util { 거듭제곱이, 문자열배열에있음, 작은값, 큰값 }8
export record 이미지머리 {9
버전: int,10
언어번호: int,11
팔레트번호: int,12
너비: int,13
높이: int,14
판행수: int,15
띠위: int,16
띠행수: int,17
노드수: int,18
보호길이: int,19
논리길이: int,20
패리티길이: int,21
프로필해시: string,22
키해시: string,23
구조해시앞: string,24
쪽번호: int,25
쪽수: int,26
노드시작: int,27
크롬번호: int,28
제목: string,29
원본줄수: int,30
세트해시: string31
}33
export record 비트기록 { 출력: ByteBuffer, 출력길이: int, 값: int, 수: int }34
export record 일치 { 길이: int, 거리: int }35
export record 비트읽기 { 값: int, 다음: int }36
export record 부풀림 { 잡은바이트: Array<int>, 출력길이: int }37
export record 원시쪽 { 머리: 이미지머리, 머리바이트: Array<int>, 띠바이트: Array<int> }39
export function 이역할변형(필드: string) -> int {40
if 문자열배열에있음(["exported", "exprName", "id", "imported", "key", "label", "local", "meta", "name", "namespace"], 필드) { return 0 }41
if 문자열배열에있음(["param", "parameter", "parameterName", "parameters", "params", "rest"], 필드) { return 1 }42
if 문자열배열에있음(["argument", "arguments", "callee", "object", "property", "qualification", "qualifier", "quasi", "quasis", "tag"], 필드) { return 2 }43
if 문자열배열에있음(["alternate", "cases", "consequent", "default", "discriminant", "finalizer", "handler", "test"], 필드) { return 3 }44
if 문자열배열에있음(["block", "body", "children", "closingElement", "closingFragment", "openingElement", "openingFragment", "program"], 필드) { return 4 }45
if 문자열배열에있음(["expression", "expressions", "init", "initializer", "left", "literal", "right", "source", "update", "value"], 필드) { return 5 }46
if 문자열배열에있음(["assertions", "attributes", "declaration", "declarations", "decorators", "directives", "elements", "members", "options", "properties", "specifiers"], 필드) { return 6 }47
if 문자열배열에있음(["bound", "callProperties", "checkType", "constraint", "elementType", "elementTypes", "extends", "extendsType", "falseType", "implements", "impltype", "indexers", "indexType", "internalSlots", "mixins", "moduleReference", "nameType", "objectType", "predicate", "returnType", "superClass", "supertype", "superTypeParameters", "this", "trueType", "typeAnnotation", "typeArguments", "typeName", "typeParameter", "typeParameters", "types", "variance"], 필드) { return 7 }48
849
}51
export function 사각안(가로: int, 세로: int, 왼쪽: int, 위: int, 너비: int, 높이: int) -> bool {52
가로 >= 왼쪽 && 가로 < 왼쪽 + 너비 && 세로 >= 위 && 세로 < 위 + 높이53
}55
export function 글자그림(글: string, 왼쪽: int, 위: int, 배율: int, 가로: int, 세로: int) -> bool {56
if 세로 < 위 || 세로 >= 위 + 5 * 배율 || 가로 < 왼쪽 { return false }57
let 글자들 = 글.scalars()58
let 상대가로 = 가로 - 왼쪽59
let 글자폭 = 4 * 배율60
let 글자색인 = 상대가로 / 글자폭61
if 글자색인 >= 글자들.length { return false }62
let 글자안가로 = 상대가로 % 글자폭63
if 글자안가로 >= 3 * 배율 { return false }64
let 열 = 글자안가로 / 배율65
let 행 = (세로 - 위) / 배율66
픽셀글꼴(글자들[글자색인]).scalars()[행 * 3 + 열] == "1"67
}69
function 비트뒤집기(값: int, 수: int) -> int {70
let mut 원본 = 값71
let mut 결과 = 072
let mut 색인 = 073
while 색인 < 수 { 결과 = 결과 * 2 + 원본 % 2; 원본 = 원본 / 2; 색인 = 색인 + 1 }74
결과75
}77
function 고정기호비트(기호: int) -> int {78
if 기호 <= 143 { return 비트뒤집기(48 + 기호, 8) }79
if 기호 <= 255 { return 비트뒤집기(400 + 기호 - 144, 9) }80
if 기호 <= 279 { return 비트뒤집기(기호 - 256, 7) }81
비트뒤집기(192 + 기호 - 280, 8)82
}84
function 고정기호길이(기호: int) -> int {85
if 기호 <= 143 { return 8 }86
if 기호 <= 255 { return 9 }87
if 기호 <= 279 { return 7 }88
889
}91
function 비트쓰기(기록: 비트기록, 값: int, 수: int) -> 비트기록 {92
let mut 출력 = 기록.출력93
let mut 출력길이 = 기록.출력길이94
let mut 대기값 = 기록.값 + 값 * 거듭제곱이(기록.수)95
let mut 대기수 = 기록.수 + 수96
while 대기수 >= 8 {97
출력.set(출력길이, 대기값 % 256); 출력길이 = 출력길이 + 198
대기값 = 대기값 / 256; 대기수 = 대기수 - 899
}100
비트기록 { 출력: 출력, 출력길이: 출력길이, 값: 대기값, 수: 대기수 }101
}103
function 고정기호쓰기(기록: 비트기록, 기호: int) -> 비트기록 {104
비트쓰기(기록, 고정기호비트(기호), 고정기호길이(기호))105
}107
function 길이밑들() -> Array<int> { [3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258] }108
function 길이더비트들() -> Array<int> { [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0] }109
function 거리밑들() -> Array<int> { [1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577] }110
function 거리더비트들() -> Array<int> { [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13] }112
function 밑색인(밑들: Array<int>, 값: int) -> int {113
let mut 색인 = 밑들.length - 1114
while 색인 >= 0 { if 값 >= 밑들[색인] { return 색인 }; 색인 = 색인 - 1 }115
-1116
}118
function 일치비트수(길이: int, 거리: int) -> int {119
let 길이색인 = 밑색인(길이밑들(), 길이)120
let 거리색인 = 밑색인(거리밑들(), 거리)121
고정기호길이(257 + 길이색인) + 길이더비트들()[길이색인] + 5 + 거리더비트들()[거리색인]122
}124
function 글자비트수(입력: ByteBuffer, 위치: int, 길이: int) -> int {125
let mut 비트 = 0126
let mut 색인 = 위치127
while 색인 < 위치 + 길이 { 비트 = 비트 + if 입력.get(색인) <= 143 { 8 } else { 9 }; 색인 = 색인 + 1 }128
비트129
}131
function 위치넣기(입력: ByteBuffer, 위치: int, 전체길이: int, 해시머리: ByteBuffer, 이전위치: ByteBuffer, 자리위치: ByteBuffer) -> bool {132
if 위치 + 3 > 전체길이 { return false }133
let 값 = 입력.get(위치) * 65536 + 입력.get(위치 + 1) * 256 + 입력.get(위치 + 2)134
let 해시 = ((값 * 506832829) % 4294967296) / 65536135
let 자리 = 위치 % 32768136
let 해시자리 = 해시 * 4137
let 이전 = 해시머리.get(해시자리) * 16777216 + 해시머리.get(해시자리 + 1) * 65536 +138
해시머리.get(해시자리 + 2) * 256 + 해시머리.get(해시자리 + 3)139
let 자리바이트 = 자리 * 4140
let mut 이전출력 = 이전위치141
이전출력.set(자리바이트, (이전 / 16777216) % 256); 이전출력.set(자리바이트 + 1, (이전 / 65536) % 256)142
이전출력.set(자리바이트 + 2, (이전 / 256) % 256); 이전출력.set(자리바이트 + 3, 이전 % 256)143
let 저장 = 위치 + 1144
let mut 자리출력 = 자리위치145
자리출력.set(자리바이트, (저장 / 16777216) % 256); 자리출력.set(자리바이트 + 1, (저장 / 65536) % 256)146
자리출력.set(자리바이트 + 2, (저장 / 256) % 256); 자리출력.set(자리바이트 + 3, 저장 % 256)147
let mut 머리출력 = 해시머리148
머리출력.set(해시자리, (저장 / 16777216) % 256); 머리출력.set(해시자리 + 1, (저장 / 65536) % 256)149
머리출력.set(해시자리 + 2, (저장 / 256) % 256); 머리출력.set(해시자리 + 3, 저장 % 256)150
true151
}153
function 일치찾기(입력: ByteBuffer, 위치: int, 전체길이: int, 해시머리: ByteBuffer, 이전위치: ByteBuffer, 자리위치: ByteBuffer) -> 일치 {154
if 위치 + 3 > 전체길이 { return 일치 { 길이: 0, 거리: 0 } }155
let 값 = 입력.get(위치) * 65536 + 입력.get(위치 + 1) * 256 + 입력.get(위치 + 2)156
let 해시 = ((값 * 506832829) % 4294967296) / 65536157
let 최소위치 = 큰값(0, 위치 - 32768)158
let 최대길이 = 작은값(258, 전체길이 - 위치)159
let 해시자리 = 해시 * 4160
let mut 후보 = 해시머리.get(해시자리) * 16777216 + 해시머리.get(해시자리 + 1) * 65536 +161
해시머리.get(해시자리 + 2) * 256 + 해시머리.get(해시자리 + 3) - 1162
let mut 찾은수 = 0163
let mut 가장길이 = 0164
let mut 가장거리 = 0165
while 후보 >= 최소위치 && 후보 >= 0 && 찾은수 < 128 {166
let 자리 = 후보 % 32768167
let 자리바이트 = 자리 * 4168
let 자리값 = 자리위치.get(자리바이트) * 16777216 + 자리위치.get(자리바이트 + 1) * 65536 +169
자리위치.get(자리바이트 + 2) * 256 + 자리위치.get(자리바이트 + 3) - 1170
if 자리값 != 후보 { 후보 = -1 }171
else {172
if 가장길이 == 0 || 가장길이 == 최대길이 || 입력.get(후보 + 가장길이) == 입력.get(위치 + 가장길이) {173
let mut 길이 = 0174
while 길이 < 최대길이 && 입력.get(후보 + 길이) == 입력.get(위치 + 길이) { 길이 = 길이 + 1 }175
if 길이 > 가장길이 {176
가장길이 = 길이; 가장거리 = 위치 - 후보177
if 가장길이 == 최대길이 { 후보 = -1 }178
}179
}180
if 후보 >= 0 {181
후보 = 이전위치.get(자리바이트) * 16777216 + 이전위치.get(자리바이트 + 1) * 65536 +182
이전위치.get(자리바이트 + 2) * 256 + 이전위치.get(자리바이트 + 3) - 1183
찾은수 = 찾은수 + 1184
}185
}186
}187
if 가장길이 < 3 || 일치비트수(가장길이, 가장거리) >= 글자비트수(입력, 위치, 가장길이) { return 일치 { 길이: 0, 거리: 0 } }188
일치 { 길이: 가장길이, 거리: 가장거리 }189
}191
function 고정일치쓰기(기록: 비트기록, 길이: int, 거리: int) -> 비트기록 {192
let 길이밑 = 길이밑들(); let 길이더 = 길이더비트들()193
let 거리밑 = 거리밑들(); let 거리더 = 거리더비트들()194
let 길이색인 = 밑색인(길이밑, 길이)195
let mut 결과 = 고정기호쓰기(기록, 257 + 길이색인)196
if 길이더[길이색인] > 0 { 결과 = 비트쓰기(결과, 길이 - 길이밑[길이색인], 길이더[길이색인]) }197
let 거리색인 = 밑색인(거리밑, 거리)198
결과 = 비트쓰기(결과, 비트뒤집기(거리색인, 5), 5)199
if 거리더[거리색인] > 0 { 결과 = 비트쓰기(결과, 거리 - 거리밑[거리색인], 거리더[거리색인]) }200
결과201
}203
export function 청크만들기(종류바이트: Bytes, 자료바이트: Bytes) -> Bytes {204
let 종류 = ByteBuffer.fromBytes(종류바이트)205
let 자료 = ByteBuffer.fromBytes(자료바이트)206
let 자료길이 = 자료.length()207
let mut 결과 = ByteBuffer.allocate(12 + 자료길이)208
결과.set(0, (자료길이 / 16777216) % 256); 결과.set(1, (자료길이 / 65536) % 256)209
결과.set(2, (자료길이 / 256) % 256); 결과.set(3, 자료길이 % 256)210
결과.copy(종류, 0, 4, 종류.length()); 결과.copy(자료, 0, 8, 자료길이)211
let mut 검사입력 = ByteBuffer.allocate(종류.length() + 자료길이)212
검사입력.copy(종류, 0, 0, 종류.length()); 검사입력.copy(자료, 0, 종류.length(), 자료길이)213
let 검사합 = Hash.crc32(검사입력.toBytes())214
let 위치 = 8 + 자료길이215
결과.set(위치, (검사합 / 16777216) % 256); 결과.set(위치 + 1, (검사합 / 65536) % 256)216
결과.set(위치 + 2, (검사합 / 256) % 256); 결과.set(위치 + 3, 검사합 % 256)217
결과.toBytes()218
}SHA256 8b5ca95ecd1c201cfe10f0cd75a82f1e4412766286a4731a2ce098fc773995ab