-
Notifications
You must be signed in to change notification settings - Fork 68
/
JPEGReadWriter2Plugin.class.st
443 lines (384 loc) · 14.6 KB
/
JPEGReadWriter2Plugin.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
"
This work is a Squeak VM Plugin version of LibJPEG.
The following sentence applies to this class:
""This software is based in part on the work of the Independent JPEG Group"".
You can read more about it at www.ijg.org
In addition to the code generated from this class, the plugin uses the following files (from LibJPEG ver. 6b):
jerror.c
jcmarker.c
jdmarker.c
jctrans.c
jcparam.c
jdapimin.c
jcapimin.c
jidctred.c
jidctflt.c
jidctfst.c
jidctint.c
jccoefct.c
jdinput.c
jdmaster.c
jdcoefct.c
jdhuff.c
jdphuff.c
jcphuff.c
jchuff.c
jcomapi.c
jcinit.c
jcmaster.c
jdcolor.c
jdtrans.c
jmemmgr.c
jutils.c
jddctmgr.c
jcdctmgr.c
jquant2.c
jquant1.c
jmemnobs.c
jfdctint.c
jfdctfst.c
jfdctflt.c
jdsample.c
jdpostct.c
jdmerge.c
jdmainct.c
jdapistd.c
jcsample.c
jcprepct.c
jcmainct.c
jccolor.c
jcapistd.c
jversion.h
jpeglib.h
jdhuff.h
jchuff.h
jerror.h
jmorecfg.h
jmemsys.h
jpegint.h
jdct.h
jinclude.h
"
Class {
#name : #JPEGReadWriter2Plugin,
#superclass : #SmartSyntaxInterpreterPlugin,
#category : #'VMMaker-Plugins'
}
{ #category : #translation }
JPEGReadWriter2Plugin class >> hasHeaderFile [
"If there is a single intrinsic header file to be associated with the plugin, here is where you want to flag"
^true
]
{ #category : #translation }
JPEGReadWriter2Plugin class >> requiresCrossPlatformFiles [
"default is ok for most, any plugin needing cross platform files must say so"
^true
]
{ #category : #translation }
JPEGReadWriter2Plugin class >> requiresPlatformFiles [
"default is ok for most, any plugin needing platform specific files must say so"
^true
]
{ #category : #'plugin support' }
JPEGReadWriter2Plugin >> compressStructSize [
<inline: #always>
^self
cCode: [self sizeof: #'struct jpeg_compress_struct']
inSmalltalk: [JPEGReadWriter2 new primJPEGCompressStructSize]
]
{ #category : #'plugin support' }
JPEGReadWriter2Plugin >> decompressStructSize [
<inline: #always>
^self
cCode: [self sizeof: #'struct jpeg_decompress_struct']
inSmalltalk: [JPEGReadWriter2 new primJPEGDecompressStructSize]
]
{ #category : #'plugin support' }
JPEGReadWriter2Plugin >> errorMgr2StructSize [
<inline: #always>
^self
cCode: [self sizeof: #'struct error_mgr2']
inSmalltalk: [JPEGReadWriter2 new primJPEGErrorMgr2StructSize]
]
{ #category : #'plugin support' }
JPEGReadWriter2Plugin >> isValidCompressionStruct: aByteArray [
<inline: #always>
^(interpreterProxy byteSizeOf: aByteArray cPtrAsOop) >= self compressStructSize
]
{ #category : #'plugin support' }
JPEGReadWriter2Plugin >> isValidDecompressionStruct: aByteArray [
<inline: #always>
^(interpreterProxy byteSizeOf: aByteArray cPtrAsOop) >= self decompressStructSize
]
{ #category : #'plugin support' }
JPEGReadWriter2Plugin >> isValidErrorMessageStruct: aByteArray [
<inline: #always>
^(interpreterProxy byteSizeOf: aByteArray cPtrAsOop) >= self errorMgr2StructSize
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primImageHeight: aJPEGDecompressStruct [
<export: true>
self primitive: 'primImageHeight' parameters: #(ByteArray).
"Various parameter checks"
(self isValidDecompressionStruct: aJPEGDecompressStruct) ifFalse:
[^interpreterProxy primitiveFail].
^(self
cCode: '((j_decompress_ptr)aJPEGDecompressStruct)->image_height'
inSmalltalk: [JPEGReadWriter2 new primImageHeight: aJPEGDecompressStruct asByteArray])
asOop: SmallInteger
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primImageNumComponents: aJPEGDecompressStruct [
<export: true>
self primitive: 'primImageNumComponents' parameters: #(ByteArray).
"Various parameter checks"
(self isValidDecompressionStruct: aJPEGDecompressStruct) ifFalse:
[^interpreterProxy primitiveFail].
^(self
cCode: '((j_decompress_ptr)aJPEGDecompressStruct)->num_components'
inSmalltalk: [JPEGReadWriter2 new primImageNumComponents: aJPEGDecompressStruct asByteArray])
asOop: SmallInteger
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primImageWidth: aJPEGDecompressStruct [
<export: true>
self primitive: 'primImageWidth' parameters: #(ByteArray).
"Various parameter checks"
(self isValidDecompressionStruct: aJPEGDecompressStruct) ifFalse:
[^interpreterProxy primitiveFail].
^(self
cCode: '((j_decompress_ptr)aJPEGDecompressStruct)->image_width'
inSmalltalk: [JPEGReadWriter2 new primImageWidth: aJPEGDecompressStruct asByteArray])
asOop: SmallInteger
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primJPEGCompressStructSize [
<export: true>
self primitive: #primJPEGCompressStructSize parameters: #().
^self compressStructSize asOop: SmallInteger
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primJPEGDecompressStructSize [
<export: true>
self primitive: #primJPEGDecompressStructSize parameters: #().
^self decompressStructSize asOop: SmallInteger
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primJPEGErrorMgr2StructSize [
<export: true>
self primitive: #primJPEGErrorMgr2StructSize parameters: #().
^self errorMgr2StructSize asOop: SmallInteger
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primJPEGPluginIsPresent [
<export: true>
self primitive: #primJPEGPluginIsPresent parameters: #().
^(self cCode: [true] inSmalltalk: [JPEGReadWriter2 primJPEGPluginIsPresent]) asOop: Boolean
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primJPEGReadHeader: aJPEGDecompressStruct fromByteArray: source errorMgr: aJPEGErrorMgr2Struct [
<export: true>
| sourceSize |
self
primitive: 'primJPEGReadHeaderfromByteArrayerrorMgr'
parameters: #(ByteArray ByteArray ByteArray).
"Various parameter checks"
((self isValidDecompressionStruct: aJPEGDecompressStruct)
and: [self isValidErrorMessageStruct: aJPEGErrorMgr2Struct]) ifFalse:
[^interpreterProxy primitiveFail].
sourceSize := interpreterProxy byteSizeOf: source cPtrAsOop.
sourceSize > 0 ifTrue:
[self primJPEGReadHeader: aJPEGDecompressStruct
fromByteArray: source
size: sourceSize
errorMgrReadHeader: aJPEGErrorMgr2Struct]
]
{ #category : #simulation }
JPEGReadWriter2Plugin >> primJPEGReadHeader: jpegDecompressStruct fromByteArray: source size: sourceSize errorMgrReadHeader: jpegErrorMgr2Struct [
"void primJPEGReadHeaderfromByteArraysizeerrorMgrReadHeader(
char* jpegDecompressStruct,
char* source,
unsigned int sourceSize,
char* jpegErrorMgr2Struct)"
<doNotGenerate>
| decompressStruct errorStruct sourceBytes |
sourceBytes := source asByteArray.
self assert: sourceBytes size >= sourceSize.
decompressStruct := jpegDecompressStruct asByteArray.
errorStruct := jpegErrorMgr2Struct asByteArray.
(self evaluateIfFailed:
[JPEGReadWriter2 new
primJPEGReadHeader: decompressStruct
fromByteArray: sourceBytes
errorMgr: errorStruct]) ifTrue: [^nil].
jpegDecompressStruct overwriteContentsWith: decompressStruct.
jpegErrorMgr2Struct overwriteContentsWith: errorStruct.
source overwriteContentsWith: sourceBytes.
^nil
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primJPEGReadImage: aJPEGDecompressStruct fromByteArray: source onForm: form doDithering: ditherFlag errorMgr: aJPEGErrorMgr2Struct [
<export: true>
| formBitmap formNativeDepth formDepth formWidth formHeight pixelsPerWord formPitch formBitmapSizeInBytes sourceSize formBitmapOOP formComponentBitSize formComponents wordsPerRow |
<var: #formBitmap type: #'unsigned int *'>
self
primitive: 'primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgr'
parameters: #(ByteArray ByteArray Form Boolean ByteArray).
formBitmapOOP := interpreterProxy fetchPointer: 0 ofObject: form.
formNativeDepth := interpreterProxy fetchInteger: 3 ofObject: form.
formWidth := interpreterProxy fetchInteger: 1 ofObject: form.
formHeight := interpreterProxy fetchInteger: 2 ofObject: form.
formDepth := formNativeDepth abs.
"Various parameter checks"
((self isValidDecompressionStruct: aJPEGDecompressStruct)
and: [self isValidErrorMessageStruct: aJPEGErrorMgr2Struct]) ifFalse:
[^interpreterProxy primitiveFail].
formComponents := formDepth ~= 8 ifTrue: [4] ifFalse: [1].
formComponentBitSize := formDepth ~= 16 ifTrue: [8] ifFalse: [4].
pixelsPerWord := 32 // (formComponents * formComponentBitSize).
wordsPerRow := (formWidth + pixelsPerWord - 1) // pixelsPerWord.
formPitch := formWidth + (pixelsPerWord-1) // pixelsPerWord * 4.
formBitmapSizeInBytes := interpreterProxy byteSizeOf: formBitmapOOP.
interpreterProxy success:
((interpreterProxy isWordsOrBytes: formBitmapOOP)
and: [formBitmapSizeInBytes >= (formPitch * formHeight)]).
interpreterProxy failed ifTrue: [^nil].
sourceSize := interpreterProxy stSizeOf: (interpreterProxy stackValue: 3).
interpreterProxy success: (sourceSize ~= 0).
interpreterProxy failed ifTrue: [^nil].
formBitmap := interpreterProxy firstIndexableField: formBitmapOOP.
self primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgrReadScanlines: aJPEGDecompressStruct
_: aJPEGErrorMgr2Struct
_: source
_: sourceSize
_: ditherFlag
_: formBitmap
_: pixelsPerWord
_: wordsPerRow
_: formNativeDepth
]
{ #category : #simulation }
JPEGReadWriter2Plugin >> primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgrReadScanlines: jpegDecompressStruct _: jpegErrorMgr2Struct _: source _: sourceSize _: ditherFlag _: formBitmap _: pixelsPerWord _: wordsPerRow _: formNativeDepth [
"void primJPEGReadImagefromByteArrayonFormdoDitheringerrorMgrReadScanlines(
char* jpegDecompressStruct,
char* jpegErrorMgr2Struct,
char* source,
unsigned int sourceSize,
int ditherFlag,
unsigned int* bitmap,
unsigned int pixelsPerWord,
unsigned int wordsPerRow,
int nativeDepth)"
<doNotGenerate>
| sourceBytes decompressStruct errorStruct form |
sourceBytes := source asByteArray.
decompressStruct := jpegDecompressStruct asByteArray.
errorStruct := jpegErrorMgr2Struct asByteArray.
(self evaluateIfFailed:
[| slave height |
slave := JPEGReadWriter2 new.
height := slave primImageWidth: decompressStruct. "cheating ;-)"
form := Form extent: wordsPerRow * pixelsPerWord @ height depth: formNativeDepth.
slave
primJPEGReadImage: decompressStruct
fromByteArray: sourceBytes
onForm: form
doDithering: true
errorMgr: errorStruct]) ifTrue: [^nil].
jpegDecompressStruct overwriteContentsWith: decompressStruct.
jpegErrorMgr2Struct overwriteContentsWith: errorStruct.
source overwriteContentsWith: sourceBytes. "could happen..."
ByteArray adoptInstance: form bits.
formBitmap overwriteContentsWith: form bits.
^nil
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primJPEGWriteImage: aJPEGCompressStruct onByteArray: destination form: form quality: quality progressiveJPEG: progressiveFlag errorMgr: aJPEGErrorMgr2Struct [
| formBitmap formWidth formHeight formNativeDepth formDepth destinationSize pixelsPerWord wordsPerRow formPitch formBitmapSizeInBytes formBitmapOOP formComponentBitSize formComponents |
<export: true>
<var: #formBitmap type: 'unsigned int *'>
<var: #destinationSize type: 'unsigned int'>
self
primitive: 'primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgr'
parameters: #(ByteArray ByteArray Form SmallInteger Boolean ByteArray).
formBitmapOOP := interpreterProxy fetchPointer: 0 ofObject: form.
formWidth := interpreterProxy fetchInteger: 1 ofObject: form.
formHeight := interpreterProxy fetchInteger: 2 ofObject: form.
formNativeDepth := interpreterProxy fetchInteger: 3 ofObject: form.
formDepth := formNativeDepth abs.
"Various parameter checks"
((self isValidCompressionStruct: aJPEGCompressStruct)
and: [self isValidErrorMessageStruct: aJPEGErrorMgr2Struct]) ifFalse:
[^interpreterProxy primitiveFail].
formComponents := formDepth ~= 8 ifTrue: [4] ifFalse: [1].
formComponentBitSize := formDepth ~= 16 ifTrue: [8] ifFalse: [4].
pixelsPerWord := 32 // (formComponents * formComponentBitSize).
wordsPerRow := (formWidth + pixelsPerWord - 1) // pixelsPerWord.
formPitch := wordsPerRow * 4.
formBitmapSizeInBytes := interpreterProxy byteSizeOf: formBitmapOOP.
interpreterProxy success:
((interpreterProxy isWordsOrBytes: formBitmapOOP) and:
[formBitmapSizeInBytes >= (formPitch * formHeight)]).
interpreterProxy failed ifTrue: [ ^ nil ].
formBitmap := interpreterProxy firstIndexableField: formBitmapOOP.
destinationSize := interpreterProxy stSizeOf: (interpreterProxy stackValue: 4).
destinationSize > 0 ifTrue:
[self primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgrWriteScanlines: formWidth
_: formHeight
_: formNativeDepth
_: formBitmap
_: aJPEGCompressStruct
_: aJPEGErrorMgr2Struct
_: quality
_: progressiveFlag
_: pixelsPerWord
_: wordsPerRow
_: destination
_: (self addressOf: destinationSize put: [:v| destinationSize := v])].
^destinationSize asOop: SmallInteger
]
{ #category : #simulation }
JPEGReadWriter2Plugin >> primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgrWriteScanlines: width _: height _: nativeDepth _: bitmap _: jpegCompressStruct _: jpegErrorMgr2Struct _: quality _: progressiveFlag _: pixelsPerWord _: wordsPerRow _: destination _: destinationSizePtr [
"void primJPEGWriteImageonByteArrayformqualityprogressiveJPEGerrorMgrWriteScanlines(
unsigned int width,
unsigned int height,
int nativeDepth,
unsigned int* bitmap,
char* jpegCompressStruct,
char* jpegErrorMgr2Struct,
int quality,
int progressiveFlag,
unsigned int pixelsPerWord,
unsigned int wordsPerRow,
char* destination,
unsigned int* destinationSizePtr)"
<doNotGenerate>
| bits form compressStruct errorStruct destinationBytes destinationSize |
bits := bitmap asByteArray.
Bitmap adoptInstance: bits.
form := Form extent: width @ height depth: nativeDepth bits: bits.
compressStruct := jpegCompressStruct asByteArray.
errorStruct := jpegErrorMgr2Struct asByteArray.
destinationBytes := destination asByteArray.
(self evaluateIfFailed:
[destinationSize :=JPEGReadWriter2 new
primJPEGWriteImage: compressStruct
onByteArray: destinationBytes
form: form
quality: quality
progressiveJPEG: progressiveFlag
errorMgr: errorStruct]) ifTrue: [^nil].
jpegCompressStruct overwriteContentsWith: compressStruct.
jpegErrorMgr2Struct overwriteContentsWith: errorStruct.
destination overwriteContentsWith: destinationBytes.
destinationSizePtr at: 0 put: destinationSize.
^nil
]
{ #category : #primitives }
JPEGReadWriter2Plugin >> primSupports8BitGrayscaleJPEGs [
<export: true>
self
primitive: 'primSupports8BitGrayscaleJPEGs'
parameters: #().
^ true asOop: Boolean
]