163 dstIdx := dstIdx + 1 |
163 dstIdx := dstIdx + 1 |
164 ]. |
164 ]. |
165 |
165 |
166 "Created: 21.7.1997 / 18:04:00 / cg" |
166 "Created: 21.7.1997 / 18:04:00 / cg" |
167 "Modified: 21.7.1997 / 18:05:47 / cg" |
167 "Modified: 21.7.1997 / 18:05:47 / cg" |
|
168 ! ! |
|
169 |
|
170 !Depth4Image methodsFor:'converting images'! |
|
171 |
|
172 anyImageAsTrueColorFormOn:aDevice |
|
173 "return a true-color device-form for the palette-image receiver. |
|
174 Supports true color devices with depths: 8, 16, 24 and 32" |
|
175 |
|
176 |depth |
|
177 nColors "{ Class: SmallInteger }" |
|
178 colorValues |
|
179 scaleRed scaleGreen scaleBlue redShift greenShift blueShift |
|
180 form imageBits bestFormat usedDeviceDepth usedDeviceBitsPerPixel |
|
181 usedDevicePadding usedDeviceBytesPerRow padd n| |
|
182 |
|
183 depth := aDevice depth. |
|
184 |
|
185 "/ gather r/g/b values for all colors in the map ... |
|
186 |
|
187 nColors := 1 bitShift:(self depth). |
|
188 |
|
189 "/ precompute scales to map from 0..100 into devices range |
|
190 "/ (this may be different for the individual components) |
|
191 |
|
192 scaleRed := ((1 bitShift:aDevice bitsRed) - 1) / 100. |
|
193 scaleGreen := ((1 bitShift:aDevice bitsGreen) - 1) / 100. |
|
194 scaleBlue := ((1 bitShift:aDevice bitsBlue) - 1) / 100. |
|
195 redShift := aDevice shiftRed. |
|
196 greenShift := aDevice shiftGreen. |
|
197 blueShift := aDevice shiftBlue. |
|
198 |
|
199 colorValues := Array uninitializedNew:nColors. |
|
200 |
|
201 0 to:nColors-1 do:[:pixel | |
|
202 |clr rv gv bv v "{ Class: SmallInteger }" | |
|
203 |
|
204 clr := self colorFromValue:pixel. |
|
205 |
|
206 rv := (clr red * scaleRed) rounded. |
|
207 gv := (clr green * scaleGreen) rounded. |
|
208 bv := (clr blue * scaleBlue) rounded. |
|
209 |
|
210 v := rv bitShift:redShift. |
|
211 v := v bitOr:(gv bitShift:greenShift). |
|
212 v := v bitOr:(bv bitShift:blueShift). |
|
213 |
|
214 colorValues at:(pixel+1) put:v. |
|
215 "/ clr print. ' ' print. |
|
216 "/ rv print. ' ' print. gv print. ' ' print. bv print. ' ' print. |
|
217 "/ ' -> ' print. v printNL. |
|
218 ]. |
|
219 |
|
220 bestFormat := self bestSupportedImageFormatFor:aDevice. |
|
221 usedDeviceDepth := bestFormat at:#depth. |
|
222 usedDeviceBitsPerPixel := bestFormat at:#bitsPerPixel. |
|
223 usedDevicePadding := bestFormat at:#padding. |
|
224 |
|
225 usedDeviceBytesPerRow := self class bytesPerRowForWidth:width depth:usedDeviceBitsPerPixel padding:usedDevicePadding. |
|
226 padd := usedDeviceBytesPerRow -( self class bytesPerRowForWidth:width depth:usedDeviceBitsPerPixel padding:8). |
|
227 imageBits := ByteArray uninitializedNew:(usedDeviceBytesPerRow * height). |
|
228 |
|
229 "/ for now, only support some depths |
|
230 |
|
231 usedDeviceBitsPerPixel == 16 ifTrue:[ |
|
232 "/ 16 bits/pixel |
|
233 |
|
234 "/ now, walk over the image and replace |
|
235 "/ colorMap indices by color values in the bits array |
|
236 |
|
237 %{ |
|
238 if (__bothSmallInteger(_INST(height), _INST(width)) |
|
239 && __isArray(colorValues) |
|
240 && __isByteArray(_INST(bytes)) |
|
241 && __isByteArray(imageBits)) { |
|
242 int r,p; |
|
243 int x, y, w, h, nPix; |
|
244 int byte; |
|
245 |
|
246 unsigned char *srcPtr = __ByteArrayInstPtr(_INST(bytes))->ba_element; |
|
247 unsigned char *dstPtr = __ByteArrayInstPtr(imageBits)->ba_element; |
|
248 OBJ *ap = __ArrayInstPtr(colorValues)->a_element; |
|
249 |
|
250 w = __intVal(_INST(width)); |
|
251 h = __intVal(_INST(height)); |
|
252 r = 0; |
|
253 p = __intVal(padd); |
|
254 nPix = w * h; |
|
255 while (nPix-- > 0) { |
|
256 unsigned idx, v; |
|
257 OBJ clr; |
|
258 |
|
259 if (r & 1) { |
|
260 idx = byte & 0xF; |
|
261 } else { |
|
262 byte = *srcPtr++; |
|
263 idx = (byte>>4) & 0xF; |
|
264 } |
|
265 clr = ap[idx]; |
|
266 v = __intVal(clr); |
|
267 #ifdef MSBFIRST |
|
268 ((short *)dstPtr)[0] = v; |
|
269 #else |
|
270 dstPtr[0] = (v>>8) & 0xFF; |
|
271 dstPtr[1] = (v) & 0xFF; |
|
272 #endif |
|
273 dstPtr += 2; |
|
274 |
|
275 if (++r == w) { |
|
276 dstPtr += p; |
|
277 r = 0; |
|
278 } |
|
279 } |
|
280 } |
|
281 %}. |
|
282 ] ifFalse:[ |
|
283 usedDeviceBitsPerPixel == 32 ifTrue:[ |
|
284 "/ 32 bits/pixel |
|
285 |
|
286 "/ now, walk over the image and replace |
|
287 "/ colorMap indices by color values in the bits array |
|
288 |
|
289 %{ |
|
290 if (__bothSmallInteger(_INST(height), _INST(width)) |
|
291 && __isArray(colorValues) |
|
292 && __isByteArray(_INST(bytes)) |
|
293 && __isByteArray(imageBits)) { |
|
294 int x, y, w, h, nPix; |
|
295 int r,p; |
|
296 int byte; |
|
297 |
|
298 unsigned char *srcPtr = __ByteArrayInstPtr(_INST(bytes))->ba_element; |
|
299 unsigned char *dstPtr = __ByteArrayInstPtr(imageBits)->ba_element; |
|
300 OBJ *ap = __ArrayInstPtr(colorValues)->a_element; |
|
301 |
|
302 w = __intVal(_INST(width)); |
|
303 h = __intVal(_INST(height)); |
|
304 r = 0; |
|
305 p = __intVal(padd); |
|
306 nPix = w * h; |
|
307 while (nPix > 0) { |
|
308 unsigned idx, v; |
|
309 OBJ clr; |
|
310 |
|
311 if (r & 1) { |
|
312 byte = *srcPtr++; |
|
313 idx = (byte>>4) & 0xF; |
|
314 } else { |
|
315 idx = byte & 0xF; |
|
316 } |
|
317 clr = ap[idx]; |
|
318 v = __intVal(clr); |
|
319 #ifdef MSBFIRST |
|
320 ((long *)dstPtr)[0] = v; |
|
321 #else |
|
322 dstPtr[0] = (v>>24) & 0xFF; |
|
323 dstPtr[1] = (v>>16) & 0xFF; |
|
324 dstPtr[2] = (v>>8) & 0xFF; |
|
325 dstPtr[3] = (v) & 0xFF; |
|
326 #endif |
|
327 dstPtr += 4; |
|
328 nPix--; |
|
329 |
|
330 if (++r == w) { |
|
331 dstPtr += p; |
|
332 r = 0; |
|
333 } |
|
334 } |
|
335 } |
|
336 %}. |
|
337 ] ifFalse:[ |
|
338 usedDeviceBitsPerPixel == 8 ifTrue:[ |
|
339 "/ 8 bits/pixel |
|
340 |
|
341 "/ now, walk over the image and replace |
|
342 "/ colorMap indices by color values in the bits array |
|
343 |
|
344 %{ |
|
345 if (__bothSmallInteger(_INST(height), _INST(width)) |
|
346 && __isArray(colorValues) |
|
347 && __isByteArray(_INST(bytes)) |
|
348 && __isByteArray(imageBits)) { |
|
349 int x, y, w, h, nPix; |
|
350 int r,p, byte; |
|
351 |
|
352 unsigned char *srcPtr = __ByteArrayInstPtr(_INST(bytes))->ba_element; |
|
353 unsigned char *dstPtr = __ByteArrayInstPtr(imageBits)->ba_element; |
|
354 OBJ *ap = __ArrayInstPtr(colorValues)->a_element; |
|
355 |
|
356 w = __intVal(_INST(width)); |
|
357 h = __intVal(_INST(height)); |
|
358 r = 0; |
|
359 p = __intVal(padd); |
|
360 |
|
361 nPix = w * h; |
|
362 while (nPix > 0) { |
|
363 unsigned idx, v; |
|
364 OBJ clr; |
|
365 |
|
366 if (r & 1) { |
|
367 byte = *srcPtr++; |
|
368 idx = (byte>>4) & 0xF; |
|
369 } else { |
|
370 idx = byte & 0xF; |
|
371 } |
|
372 clr = ap[idx]; |
|
373 v = __intVal(clr); |
|
374 |
|
375 dstPtr[0] = v; |
|
376 |
|
377 dstPtr += 1; |
|
378 nPix--; |
|
379 |
|
380 if (++r == w) { |
|
381 dstPtr += p; |
|
382 r = 0; |
|
383 } |
|
384 } |
|
385 } |
|
386 %}. |
|
387 ] ifFalse:[ |
|
388 usedDeviceBitsPerPixel == 24 ifTrue:[ |
|
389 "/ 24 bits/pixel |
|
390 |
|
391 "/ now, walk over the image and replace |
|
392 "/ colorMap indices by color values in the bits array |
|
393 |
|
394 %{ |
|
395 if (__bothSmallInteger(_INST(height), _INST(width)) |
|
396 && __isArray(colorValues) |
|
397 && __isByteArray(_INST(bytes)) |
|
398 && __isByteArray(imageBits)) { |
|
399 int x, y, w, h, nPix; |
|
400 int r, p, byte; |
|
401 |
|
402 unsigned char *srcPtr = __ByteArrayInstPtr(_INST(bytes))->ba_element; |
|
403 unsigned char *dstPtr = __ByteArrayInstPtr(imageBits)->ba_element; |
|
404 OBJ *ap = __ArrayInstPtr(colorValues)->a_element; |
|
405 |
|
406 w = __intVal(_INST(width)); |
|
407 h = __intVal(_INST(height)); |
|
408 r = 0; |
|
409 p = __intVal(padd); |
|
410 |
|
411 nPix = w * h; |
|
412 while (nPix > 0) { |
|
413 unsigned idx, v; |
|
414 OBJ clr; |
|
415 |
|
416 if (r & 1) { |
|
417 byte = *srcPtr++; |
|
418 idx = (byte>>4) & 0xF; |
|
419 } else { |
|
420 idx = byte & 0xF; |
|
421 } |
|
422 clr = ap[idx]; |
|
423 v = __intVal(clr); |
|
424 |
|
425 dstPtr[0] = (v>>16) & 0xFF; |
|
426 dstPtr[1] = (v>>8) & 0xFF; |
|
427 dstPtr[2] = (v) & 0xFF; |
|
428 |
|
429 dstPtr += 3; |
|
430 nPix--; |
|
431 |
|
432 if (++r == w) { |
|
433 dstPtr += p; |
|
434 r = 0; |
|
435 } |
|
436 } |
|
437 } |
|
438 %}. |
|
439 ] ifFalse:[ |
|
440 'Image [warning]: unimplemented trueColor depth in anyImageAsTrueColorFormOn: ' errorPrint. usedDeviceBitsPerPixel errorPrintCR. |
|
441 ^ nil |
|
442 ] |
|
443 ] |
|
444 ] |
|
445 ]. |
|
446 |
|
447 imageBits isNil ifTrue:[ |
|
448 ^ nil |
|
449 ]. |
|
450 |
|
451 form := Form width:width height:height depth:usedDeviceDepth on:aDevice. |
|
452 form isNil ifTrue:[^ nil]. |
|
453 form initGC. |
|
454 |
|
455 form |
|
456 copyBitsFrom:imageBits |
|
457 bitsPerPixel:usedDeviceBitsPerPixel |
|
458 depth:usedDeviceDepth |
|
459 padding:usedDevicePadding |
|
460 width:width height:height |
|
461 x:0 y:0 |
|
462 toX:0 y:0. |
|
463 |
|
464 ^ form |
|
465 |
|
466 "Created: 20.10.1995 / 22:05:10 / cg" |
|
467 "Modified: 21.10.1995 / 19:30:26 / cg" |
|
468 |
|
469 |
|
470 ! |
|
471 |
|
472 greyImageAsTrueColorFormOn:aDevice |
|
473 "return a true-color device-form for the grey-image receiver. |
|
474 Supports true color devices with depths: 8, 16, 24 and 32" |
|
475 |
|
476 |f| |
|
477 |
|
478 f := self anyImageAsTrueColorFormOn:aDevice. |
|
479 f notNil ifTrue:[^ f]. |
|
480 ^ super greyImageAsTrueColorFormOn:aDevice |
|
481 |
|
482 "Created: / 24.7.1998 / 01:21:28 / cg" |
|
483 ! |
|
484 |
|
485 paletteImageAsTrueColorFormOn:aDevice |
|
486 "return a true-color device-form for the palette-image receiver. |
|
487 Supports true color devices with depths: 8, 16, 24 and 32" |
|
488 |
|
489 |f| |
|
490 |
|
491 f := self anyImageAsTrueColorFormOn:aDevice. |
|
492 f notNil ifTrue:[^ f]. |
|
493 ^ super paletteImageAsTrueColorFormOn:aDevice |
|
494 |
|
495 "Created: / 24.7.1998 / 01:20:46 / cg" |
|
496 ! |
|
497 |
|
498 rgbImageAsTrueColorFormOn:aDevice |
|
499 "return a true-color device-form for the rgb-image receiver. |
|
500 Supports true color devices with depths: 8, 16, 24 and 32" |
|
501 |
|
502 |f| |
|
503 |
|
504 f := self anyImageAsTrueColorFormOn:aDevice. |
|
505 f notNil ifTrue:[^ f]. |
|
506 ^ super rgbImageAsTrueColorFormOn:aDevice |
|
507 |
|
508 "Created: / 24.7.1998 / 01:21:57 / cg" |
168 ! ! |
509 ! ! |
169 |
510 |
170 !Depth4Image methodsFor:'dither helpers'! |
511 !Depth4Image methodsFor:'dither helpers'! |
171 |
512 |
172 orderedDitheredGrayBitsWithDitherMatrix:ditherMatrix ditherWidth:dW depth:depth |
513 orderedDitheredGrayBitsWithDitherMatrix:ditherMatrix ditherWidth:dW depth:depth |