slow.monster

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.
3import std.bytes { Bytes }
4import std.hash
5import plan { 보호길이, 프로필해시, 픽셀글꼴 }
6import util { 거듭제곱이, 문자열배열에있음, 작은값, 큰값 }
8export 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 세트해시: string
33export record 비트기록 { 출력: ByteBuffer, 출력길이: int, 값: int, 수: int }
34export record 일치 { 길이: int, 거리: int }
35export record 비트읽기 { 값: int, 다음: int }
36export record 부풀림 { 잡은바이트: Array<int>, 출력길이: int }
37export record 원시쪽 { 머리: 이미지머리, 머리바이트: Array<int>, 띠바이트: Array<int> }
39export 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 8
51export function 사각안(가로: int, 세로: int, 왼쪽: int, 위: int, 너비: int, 높이: int) -> bool {
52 가로 >= 왼쪽 && 가로 < 왼쪽 + 너비 && 세로 >= 위 && 세로 < 위 + 높이
55export 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"
69function 비트뒤집기(값: int, 수: int) -> int {
70 let mut 원본 = 값
71 let mut 결과 = 0
72 let mut 색인 = 0
73 while 색인 < 수 { 결과 = 결과 * 2 + 원본 % 2; 원본 = 원본 / 2; 색인 = 색인 + 1 }
74 결과
77function 고정기호비트(기호: 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)
84function 고정기호길이(기호: int) -> int {
85 if 기호 <= 143 { return 8 }
86 if 기호 <= 255 { return 9 }
87 if 기호 <= 279 { return 7 }
88 8
91function 비트쓰기(기록: 비트기록, 값: int, 수: int) -> 비트기록 {
92 let mut 출력 = 기록.출력
93 let mut 출력길이 = 기록.출력길이
94 let mut 대기값 = 기록.값 + 값 * 거듭제곱이(기록.수)
95 let mut 대기수 = 기록.수 + 수
96 while 대기수 >= 8 {
97 출력.set(출력길이, 대기값 % 256); 출력길이 = 출력길이 + 1
98 대기값 = 대기값 / 256; 대기수 = 대기수 - 8
99 }
100 비트기록 { 출력: 출력, 출력길이: 출력길이, 값: 대기값, 수: 대기수 }
103function 고정기호쓰기(기록: 비트기록, 기호: int) -> 비트기록 {
104 비트쓰기(기록, 고정기호비트(기호), 고정기호길이(기호))
107function 길이밑들() -> 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] }
108function 길이더비트들() -> 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] }
109function 거리밑들() -> 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] }
110function 거리더비트들() -> 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] }
112function 밑색인(밑들: Array<int>, 값: int) -> int {
113 let mut 색인 = 밑들.length - 1
114 while 색인 >= 0 { if 값 >= 밑들[색인] { return 색인 }; 색인 = 색인 - 1 }
115 -1
118function 일치비트수(길이: int, 거리: int) -> int {
119 let 길이색인 = 밑색인(길이밑들(), 길이)
120 let 거리색인 = 밑색인(거리밑들(), 거리)
121 고정기호길이(257 + 길이색인) + 길이더비트들()[길이색인] + 5 + 거리더비트들()[거리색인]
124function 글자비트수(입력: ByteBuffer, 위치: int, 길이: int) -> int {
125 let mut 비트 = 0
126 let mut 색인 = 위치
127 while 색인 < 위치 + 길이 { 비트 = 비트 + if 입력.get(색인) <= 143 { 8 } else { 9 }; 색인 = 색인 + 1 }
128 비트
131function 위치넣기(입력: 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) / 65536
135 let 자리 = 위치 % 32768
136 let 해시자리 = 해시 * 4
137 let 이전 = 해시머리.get(해시자리) * 16777216 + 해시머리.get(해시자리 + 1) * 65536 +
138 해시머리.get(해시자리 + 2) * 256 + 해시머리.get(해시자리 + 3)
139 let 자리바이트 = 자리 * 4
140 let mut 이전출력 = 이전위치
141 이전출력.set(자리바이트, (이전 / 16777216) % 256); 이전출력.set(자리바이트 + 1, (이전 / 65536) % 256)
142 이전출력.set(자리바이트 + 2, (이전 / 256) % 256); 이전출력.set(자리바이트 + 3, 이전 % 256)
143 let 저장 = 위치 + 1
144 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 true
153function 일치찾기(입력: 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) / 65536
157 let 최소위치 = 큰값(0, 위치 - 32768)
158 let 최대길이 = 작은값(258, 전체길이 - 위치)
159 let 해시자리 = 해시 * 4
160 let mut 후보 = 해시머리.get(해시자리) * 16777216 + 해시머리.get(해시자리 + 1) * 65536 +
161 해시머리.get(해시자리 + 2) * 256 + 해시머리.get(해시자리 + 3) - 1
162 let mut 찾은수 = 0
163 let mut 가장길이 = 0
164 let mut 가장거리 = 0
165 while 후보 >= 최소위치 && 후보 >= 0 && 찾은수 < 128 {
166 let 자리 = 후보 % 32768
167 let 자리바이트 = 자리 * 4
168 let 자리값 = 자리위치.get(자리바이트) * 16777216 + 자리위치.get(자리바이트 + 1) * 65536 +
169 자리위치.get(자리바이트 + 2) * 256 + 자리위치.get(자리바이트 + 3) - 1
170 if 자리값 != 후보 { 후보 = -1 }
171 else {
172 if 가장길이 == 0 || 가장길이 == 최대길이 || 입력.get(후보 + 가장길이) == 입력.get(위치 + 가장길이) {
173 let mut 길이 = 0
174 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) - 1
183 찾은수 = 찾은수 + 1
184 }
185 }
186 }
187 if 가장길이 < 3 || 일치비트수(가장길이, 가장거리) >= 글자비트수(입력, 위치, 가장길이) { return 일치 { 길이: 0, 거리: 0 } }
188 일치 { 길이: 가장길이, 거리: 가장거리 }
191function 고정일치쓰기(기록: 비트기록, 길이: 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 결과
203export 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()

SHA256 8b5ca95ecd1c201cfe10f0cd75a82f1e4412766286a4731a2ce098fc773995ab