189
189
190
190
/***********************************************************************
191
191
**
192
- */ void RGB_To_Bin (REBYTE * bin , REBYTE * rgba , REBINT len , REBOOL alpha )
192
+ */ void Color_To_Bin (REBYTE * bin , REBYTE * rgba , REBINT len , REBCNT format )
193
193
/*
194
+ ** Convert internal image (integer) to binary string according requested order
195
+ **
194
196
***********************************************************************/
195
197
{
196
- // Convert internal image (integer) to RGB/A order binary string:
197
- if (alpha ) {
198
+ REBINT c0 , c1 , c2 , c3 ;
199
+ REBINT alpha = 0 ;
200
+
201
+ switch (format ) {
202
+ case SYM_RGB : c0 = C_R ; c1 = C_G ; c2 = C_B ; c3 = C_A ; break ;
203
+ case SYM_RGBA : c0 = C_R ; c1 = C_G ; c2 = C_B ; c3 = C_A ; alpha = 1 ; break ;
204
+ case SYM_RGBO : c0 = C_R ; c1 = C_G ; c2 = C_B ; c3 = C_A ; alpha = -1 ; break ;
205
+ case SYM_ARGB : c0 = C_A ; c1 = C_R ; c2 = C_G ; c3 = C_B ; alpha = 1 ; break ;
206
+ case SYM_ORGB : c0 = C_A ; c1 = C_R ; c2 = C_G ; c3 = C_B ; alpha = -1 ; break ;
207
+
208
+ case SYM_BGRA : c0 = C_B ; c1 = C_G ; c2 = C_R ; c3 = C_A ; alpha = 1 ; break ;
209
+ case SYM_BGRO : c0 = C_B ; c1 = C_G ; c2 = C_R ; c3 = C_A ; alpha = -1 ; break ;
210
+ case SYM_ABGR : c0 = C_A ; c1 = C_B ; c2 = C_G ; c3 = C_R ; alpha = 1 ; break ;
211
+ case SYM_OBGR : c0 = C_A ; c1 = C_B ; c2 = C_G ; c3 = C_R ; alpha = -1 ; break ;
212
+ case SYM_BGR : c0 = C_B ; c1 = C_G ; c2 = C_R ; c3 = C_A ; break ;
213
+ default : return ;
214
+ }
215
+
216
+ if (alpha > 0 ) {
198
217
for (; len > 0 ; len -- , rgba += 4 , bin += 4 ) {
199
- bin [0 ] = rgba [C_R ];
200
- bin [1 ] = rgba [C_G ];
201
- bin [2 ] = rgba [C_B ];
202
- bin [3 ] = rgba [C_A ];
218
+ bin [0 ] = rgba [c0 ];
219
+ bin [1 ] = rgba [c1 ];
220
+ bin [2 ] = rgba [c2 ];
221
+ bin [3 ] = rgba [c3 ];
222
+ }
223
+ } else if (alpha < 0 ) {
224
+ if (c0 == C_A ) {
225
+ for (; len > 0 ; len -- , rgba += 4 , bin += 4 ) {
226
+ bin [0 ] = 255 - rgba [c0 ];
227
+ bin [1 ] = rgba [c1 ];
228
+ bin [2 ] = rgba [c2 ];
229
+ bin [3 ] = rgba [c3 ];
230
+ }
231
+ } else {
232
+ for (; len > 0 ; len -- , rgba += 4 , bin += 4 ) {
233
+ bin [0 ] = rgba [c0 ];
234
+ bin [1 ] = rgba [c1 ];
235
+ bin [2 ] = rgba [c2 ];
236
+ bin [3 ] = 255 - rgba [c3 ];
237
+ }
203
238
}
204
239
} else {
205
- // Only the RGB part:
240
+ // Result without alpha
206
241
for (; len > 0 ; len -- , rgba += 4 , bin += 3 ) {
207
- bin [0 ] = rgba [C_R ];
208
- bin [1 ] = rgba [C_G ];
209
- bin [2 ] = rgba [C_B ];
242
+ bin [0 ] = rgba [c0 ];
243
+ bin [1 ] = rgba [c1 ];
244
+ bin [2 ] = rgba [c2 ];
210
245
}
211
246
}
212
247
}
213
248
249
+ /***********************************************************************
250
+ **
251
+ */ void Bin_To_Color (REBYTE * trg , REBYTE * src , REBINT len , REBCNT format )
252
+ /*
253
+ ** Convert external binary is specified color format to internal image
254
+ **
255
+ ***********************************************************************/
256
+ {
257
+ REBINT r , g , b , a ;
258
+ REBINT alpha = 0 ;
259
+ REBCNT * clr = (REBCNT * )trg ;
260
+
261
+ switch (format ) {
262
+ case SYM_RGBA : r = 0 ; g = 1 ; b = 2 ; a = 3 ; alpha = 1 ; break ;
263
+ case SYM_RGBO : r = 0 ; g = 1 ; b = 2 ; a = 3 ; alpha = -1 ; break ;
264
+ case SYM_ARGB : a = 0 ; r = 1 ; g = 2 ; b = 3 ; alpha = 1 ; break ;
265
+ case SYM_ORGB : a = 0 ; r = 1 ; g = 2 ; b = 3 ; alpha = -1 ; break ;
266
+
267
+ case SYM_BGRA : b = 0 ; g = 1 ; r = 2 ; a = 3 ; alpha = 1 ; break ;
268
+ case SYM_BGRO : b = 0 ; g = 1 ; r = 2 ; a = 3 ; alpha = -1 ; break ;
269
+ case SYM_ABGR : a = 0 ; b = 1 ; g = 2 ; r = 3 ; alpha = 1 ; break ;
270
+ case SYM_OBGR : a = 0 ; b = 1 ; g = 2 ; r = 3 ; alpha = -1 ; break ;
271
+ default : return ;
272
+ }
273
+
274
+ if (alpha > 0 ) {
275
+ for (; len > 0 ; len -- , src += 4 , clr ++ ) {
276
+ clr [0 ] = TO_PIXEL_COLOR (src [r ], src [g ], src [b ], src [a ]);
277
+ }
278
+ } else {
279
+ for (; len > 0 ; len -- , src += 4 , clr ++ ) {
280
+ clr [0 ] = TO_PIXEL_COLOR (src [r ], src [g ], src [b ], 255 - src [a ]);
281
+ }
282
+ }
283
+ }
214
284
215
285
/***********************************************************************
216
286
**
249
319
250
320
/***********************************************************************
251
321
**
252
- */ void Alpha_To_Bin (REBYTE * bin , REBYTE * rgba , REBINT len )
322
+ */ void Alpha_To_Bin (REBYTE * bin , REBYTE * rgba , REBINT len , REBCNT type )
253
323
/*
254
324
***********************************************************************/
255
325
{
256
- for (; len > 0 ; len -- , rgba += 4 )
257
- * bin ++ = rgba [C_A ];
326
+ if (type == SYM_ALPHA ) {
327
+ for (; len > 0 ; len -- , rgba += 4 )
328
+ * bin ++ = rgba [C_A ];
329
+ } else { // SYM_OPACITY
330
+ for (; len > 0 ; len -- , rgba += 4 )
331
+ * bin ++ = 255 - rgba [C_A ];
332
+ }
258
333
}
259
334
260
-
261
335
/***********************************************************************
262
336
**
263
- */ void Bin_To_Alpha (REBYTE * rgba , REBCNT size , REBYTE * bin , REBINT len )
337
+ */ void Bin_To_Alpha (REBYTE * rgba , REBCNT size , REBYTE * bin , REBINT len , REBCNT type )
264
338
/*
265
339
***********************************************************************/
266
340
{
267
341
if (len > (REBINT )size ) len = size ; // avoid over-run
268
342
269
- for (; len > 0 ; len -- , rgba += 4 )
270
- rgba [C_A ] = * bin ++ ;
343
+ if (type == SYM_ALPHA ) {
344
+ for (; len > 0 ; len -- , rgba += 4 )
345
+ rgba [C_A ] = * bin ++ ;
346
+ } else { // SYM_OPACITY
347
+ for (; len > 0 ; len -- , rgba += 4 )
348
+ rgba [C_A ] = 255 - * bin ++ ;
349
+ }
271
350
}
272
351
273
352
288
367
return 0 ;
289
368
}
290
369
370
+ /***********************************************************************
371
+ **
372
+ */ void Tuple_To_Color (REBCNT format , REBVAL * tuple , REBCNT * rgba )
373
+ /*
374
+ ***********************************************************************/
375
+ {
376
+ Bin_To_Color ((REBYTE * )rgba , VAL_TUPLE (tuple ), 1 , format );
377
+ }
291
378
292
379
/***********************************************************************
293
380
**
@@ -474,7 +561,7 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
474
561
475
562
// Load alpha channel data:
476
563
if (IS_BINARY (block )) {
477
- Bin_To_Alpha (ip , size , VAL_BIN_DATA (block ), VAL_LEN (block ));
564
+ Bin_To_Alpha (ip , size , VAL_BIN_DATA (block ), VAL_LEN (block ), SYM_ALPHA );
478
565
// VAL_IMAGE_TRANSP(value)=VITT_ALPHA;
479
566
block ++ ;
480
567
}
@@ -1182,6 +1269,7 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
1182
1269
REBSER * nser ;
1183
1270
REBSER * series = VAL_SERIES (data );
1184
1271
REBCNT * dp ;
1272
+ REBCNT sym ;
1185
1273
1186
1274
len = VAL_TAIL (data ) - index ;
1187
1275
len = MAX (len , 0 );
@@ -1192,9 +1280,10 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
1192
1280
else if (IS_DECIMAL (sel )) n = (REBINT )VAL_DECIMAL (sel );
1193
1281
else if (IS_LOGIC (sel )) n = (VAL_LOGIC (sel ) ? 1 : 2 );
1194
1282
else if (IS_WORD (sel )) {
1283
+ sym = VAL_WORD_CANON (sel );
1195
1284
if (val == 0 ) {
1196
1285
val = pvs -> value = pvs -> store ;
1197
- switch (VAL_WORD_CANON ( sel ) ) {
1286
+ switch (sym ) {
1198
1287
1199
1288
case SYM_SIZE :
1200
1289
VAL_SET (val , REB_PAIR );
@@ -1203,16 +1292,32 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
1203
1292
break ;
1204
1293
1205
1294
case SYM_RGB :
1295
+ case SYM_BGR :
1206
1296
nser = Make_Binary (len * 3 );
1207
1297
SERIES_TAIL (nser ) = len * 3 ;
1208
- RGB_To_Bin (QUAD_HEAD (nser ), src , len , FALSE);
1298
+ Color_To_Bin (QUAD_HEAD (nser ), src , len , sym );
1299
+ Set_Binary (val , nser );
1300
+ break ;
1301
+
1302
+ case SYM_RGBA :
1303
+ case SYM_RGBO :
1304
+ case SYM_BGRA :
1305
+ case SYM_BGRO :
1306
+ case SYM_ARGB :
1307
+ case SYM_ABGR :
1308
+ case SYM_ORGB :
1309
+ case SYM_OBGR :
1310
+ nser = Make_Binary (len * 4 );
1311
+ SERIES_TAIL (nser ) = len * 4 ;
1312
+ Color_To_Bin (QUAD_HEAD (nser ), src , len , sym );
1209
1313
Set_Binary (val , nser );
1210
1314
break ;
1211
1315
1212
1316
case SYM_ALPHA :
1317
+ case SYM_OPACITY :
1213
1318
nser = Make_Binary (len );
1214
1319
SERIES_TAIL (nser ) = len ;
1215
- Alpha_To_Bin (QUAD_HEAD (nser ), src , len );
1320
+ Alpha_To_Bin (QUAD_HEAD (nser ), src , len , sym );
1216
1321
Set_Binary (val , nser );
1217
1322
break ;
1218
1323
@@ -1223,7 +1328,7 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
1223
1328
1224
1329
} else {
1225
1330
1226
- switch (VAL_WORD_CANON ( sel ) ) {
1331
+ switch (sym ) {
1227
1332
1228
1333
case SYM_SIZE :
1229
1334
if (!IS_PAIR (val ) || !VAL_PAIR_X (val )) return PE_BAD_SET ;
@@ -1243,13 +1348,36 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
1243
1348
} else return PE_BAD_SET ;
1244
1349
break ;
1245
1350
1351
+ case SYM_RGBA :
1352
+ case SYM_RGBO :
1353
+ case SYM_BGRA :
1354
+ case SYM_BGRO :
1355
+ case SYM_ARGB :
1356
+ case SYM_ABGR :
1357
+ case SYM_ORGB :
1358
+ case SYM_OBGR :
1359
+ if (IS_TUPLE (val )) {
1360
+ if (VAL_TUPLE_LEN (val ) != 4 ) return PE_BAD_ARGUMENT ;
1361
+ REBCNT color = 0 ;
1362
+ Tuple_To_Color (sym , val , & color );
1363
+ Fill_Line ((REBCNT * )src , color , len , FALSE);
1364
+ } else if (IS_INTEGER (val )) {
1365
+ n = VAL_INT32 (val );
1366
+ if (n < 0 || n > 255 ) return PE_BAD_RANGE ;
1367
+ Fill_Line ((REBCNT * )src , TO_PIXEL_COLOR (n ,n ,n ,n ), len , FALSE);
1368
+ } else if (IS_BINARY (val )) {
1369
+ Bin_To_Color (src , VAL_BIN_DATA (val ), VAL_LEN (val ) / 4 , sym );
1370
+ } else return PE_BAD_SET ;
1371
+ break ;
1372
+
1246
1373
case SYM_ALPHA :
1374
+ case SYM_OPACITY :
1247
1375
if (IS_INTEGER (val )) {
1248
1376
n = VAL_INT32 (val );
1249
1377
if (n < 0 || n > 255 ) return PE_BAD_RANGE ;
1250
1378
Fill_Alpha_Line (src , (REBYTE )n , len );
1251
1379
} else if (IS_BINARY (val )) {
1252
- Bin_To_Alpha (src , len , VAL_BIN_DATA (val ), VAL_LEN (val ));
1380
+ Bin_To_Alpha (src , len , VAL_BIN_DATA (val ), VAL_LEN (val ), sym );
1253
1381
} else return PE_BAD_SET ;
1254
1382
break ;
1255
1383
0 commit comments