-
Notifications
You must be signed in to change notification settings - Fork 71
/
BMPReadWriterPlugin.class.st
97 lines (86 loc) · 3.4 KB
/
BMPReadWriterPlugin.class.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"
A plugin to provide fast read and write of .bmp files
"
Class {
#name : #BMPReadWriterPlugin,
#superclass : #InterpreterPlugin,
#category : #'VMMaker-Plugins'
}
{ #category : #primitives }
BMPReadWriterPlugin >> primitiveRead24BmpLine [
| width formBitsIndex formBitsOop pixelLineOop formBitsSize formBits pixelLineSize pixelLine |
<export: true>
<inline: false>
<var: #formBits type: 'unsigned int *'>
<var: #pixelLine type: 'unsigned char *'>
interpreterProxy methodArgumentCount = 4
ifFalse:[^interpreterProxy primitiveFail].
width := interpreterProxy stackIntegerValue: 0.
width <= 0 ifTrue:[^interpreterProxy primitiveFail].
formBitsIndex := interpreterProxy stackIntegerValue: 1.
formBitsOop := interpreterProxy stackObjectValue: 2.
pixelLineOop := interpreterProxy stackObjectValue: 3.
interpreterProxy failed ifTrue:[^nil].
(interpreterProxy isWords: formBitsOop)
ifFalse:[^interpreterProxy primitiveFail].
(interpreterProxy isBytes: pixelLineOop)
ifFalse:[^interpreterProxy primitiveFail].
formBitsSize := interpreterProxy slotSizeOf: formBitsOop.
formBits := interpreterProxy firstIndexableField: formBitsOop.
pixelLineSize := interpreterProxy slotSizeOf: pixelLineOop.
pixelLine := interpreterProxy firstIndexableField: pixelLineOop.
(formBitsIndex + width <= formBitsSize and:[width*3 <= pixelLineSize])
ifFalse:[^interpreterProxy primitiveFail].
"do the actual work"
self cCode:'
formBits += formBitsIndex-1;
while(width--) {
unsigned int rgb;
rgb = (*pixelLine++);
rgb += (*pixelLine++) << 8;
rgb += (*pixelLine++) << 16;
if(rgb) rgb |= 0xFF000000; else rgb |= 0xFF000001;
*formBits++ = rgb;
}
' inSmalltalk:[formBits. pixelLine. ^interpreterProxy primitiveFail].
interpreterProxy pop: 4. "args"
]
{ #category : #primitives }
BMPReadWriterPlugin >> primitiveWrite24BmpLine [
| width formBitsIndex formBitsOop pixelLineOop formBitsSize formBits pixelLineSize pixelLine |
<export: true>
<inline: false>
<var: #formBits type: 'unsigned int *'>
<var: #pixelLine type: 'unsigned char *'>
interpreterProxy methodArgumentCount = 4
ifFalse:[^interpreterProxy primitiveFail].
width := interpreterProxy stackIntegerValue: 0.
width <= 0 ifTrue:[^interpreterProxy primitiveFail].
formBitsIndex := interpreterProxy stackIntegerValue: 1.
formBitsOop := interpreterProxy stackObjectValue: 2.
pixelLineOop := interpreterProxy stackObjectValue: 3.
interpreterProxy failed ifTrue:[^nil].
(interpreterProxy isWords: formBitsOop)
ifFalse:[^interpreterProxy primitiveFail].
(interpreterProxy isBytes: pixelLineOop)
ifFalse:[^interpreterProxy primitiveFail].
formBitsSize := interpreterProxy slotSizeOf: formBitsOop.
formBits := interpreterProxy firstIndexableField: formBitsOop.
pixelLineSize := interpreterProxy slotSizeOf: pixelLineOop.
pixelLine := interpreterProxy firstIndexableField: pixelLineOop.
(formBitsIndex + width <= formBitsSize and:[width*3 <= pixelLineSize])
ifFalse:[^interpreterProxy primitiveFail].
"do the actual work. Read 32 bit at a time from formBits, and store the low order 24 bits
or each word into pixelLine in little endian order."
self cCode:'
formBits += formBitsIndex-1;
while(width--) {
unsigned int rgb;
rgb = *formBits++;
(*pixelLine++) = (rgb ) & 0xFF;
(*pixelLine++) = (rgb >> 8 ) & 0xFF;
(*pixelLine++) = (rgb >> 16) & 0xFF;
}
' inSmalltalk:[formBits. pixelLine. ^interpreterProxy primitiveFail].
interpreterProxy pop: 4. "args"
]