1 /* ************************************************************************** */
2 /* * For conditions of distribution and use, * */
3 /* * see copyright notice in libmng.h * */
4 /* ************************************************************************** */
5 /* * * */
6 /* * project : libmng * */
7 /* * file : libmng_filter.c copyright (c) 2000-2004 G.Juyn * */
8 /* * version : 1.0.9 * */
9 /* * * */
10 /* * purpose : Filtering routines (implementation) * */
11 /* * * */
12 /* * author : G.Juyn * */
13 /* * * */
14 /* * comment : implementation of the filtering routines * */
15 /* * * */
16 /* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
17 /* * - changed strict-ANSI stuff * */
18 /* * 0.5.1 - 05/12/2000 - G.Juyn * */
19 /* * - changed trace to macro for callback error-reporting * */
20 /* * * */
21 /* * 0.9.2 - 08/05/2000 - G.Juyn * */
22 /* * - changed file-prefixes * */
23 /* * * */
24 /* * 0.9.3 - 09/07/2000 - G.Juyn * */
25 /* * - added support for new filter_types * */
26 /* * * */
27 /* * 1.0.5 - 08/07/2002 - G.Juyn * */
28 /* * - added test-option for PNG filter method 193 (=no filter) * */
29 /* * 1.0.5 - 08/19/2002 - G.Juyn * */
30 /* * - B597134 - libmng pollutes the linker namespace * */
31 /* * * */
32 /* * 1.0.6 - 07/07/2003 - G.R-P * */
33 /* * - reversed some loops to use decrementing counter * */
34 /* * * */
35 /* * 1.0.9 - 12/20/2004 - G.Juyn * */
36 /* * - cleaned up macro-invocations (thanks to D. Airlie) * */
37 /* * * */
38 /* ************************************************************************** */
39
40 #include "libmng.h"
41 #include "libmng_data.h"
42 #include "libmng_error.h"
43 #include "libmng_trace.h"
44 #ifdef __BORLANDC__
45 #pragma hdrstop
46 #endif
47 #include "libmng_filter.h"
48
49 #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
50 #pragma option -A /* force ANSI-C */
51 #endif
52
53 /* ************************************************************************** */
54
55 #ifdef MNG_INCLUDE_FILTERS
56
57 /* ************************************************************************** */
58
filter_sub(mng_datap pData)59 MNG_LOCAL mng_retcode filter_sub (mng_datap pData)
60 {
61 mng_uint32 iBpp;
62 mng_uint8p pRawx;
63 mng_uint8p pRawx_prev;
64 mng_int32 iX;
65
66 #ifdef MNG_SUPPORT_TRACE
67 MNG_TRACE (pData, MNG_FN_FILTER_SUB, MNG_LC_START);
68 #endif
69
70 iBpp = pData->iFilterbpp;
71 pRawx = pData->pWorkrow + pData->iPixelofs + iBpp;
72 pRawx_prev = pData->pWorkrow + pData->iPixelofs;
73
74 for (iX = iBpp; iX < pData->iRowsize; iX++)
75 {
76 *pRawx = (mng_uint8)(*pRawx + *pRawx_prev);
77 pRawx++;
78 pRawx_prev++;
79 }
80
81 #ifdef MNG_SUPPORT_TRACE
82 MNG_TRACE (pData, MNG_FN_FILTER_SUB, MNG_LC_END);
83 #endif
84
85 return MNG_NOERROR;
86 }
87
88 /* ************************************************************************** */
89
filter_up(mng_datap pData)90 MNG_LOCAL mng_retcode filter_up (mng_datap pData)
91 {
92 mng_uint8p pRawx;
93 mng_uint8p pPriorx;
94 mng_int32 iX;
95
96 #ifdef MNG_SUPPORT_TRACE
97 MNG_TRACE (pData, MNG_FN_FILTER_UP, MNG_LC_START);
98 #endif
99
100 pRawx = pData->pWorkrow + pData->iPixelofs;
101 pPriorx = pData->pPrevrow + pData->iPixelofs;
102
103 #ifdef MNG_DECREMENT_LOOPS
104 for (iX = pData->iRowsize - 1; iX >= 0; iX--)
105 #else
106 for (iX = 0; iX < pData->iRowsize; iX++)
107 #endif
108 {
109 *pRawx = (mng_uint8)(*pRawx + *pPriorx);
110 pRawx++;
111 pPriorx++;
112 }
113
114 #ifdef MNG_SUPPORT_TRACE
115 MNG_TRACE (pData, MNG_FN_FILTER_UP, MNG_LC_END);
116 #endif
117
118 return MNG_NOERROR;
119 }
120
121 /* ************************************************************************** */
122
filter_average(mng_datap pData)123 MNG_LOCAL mng_retcode filter_average (mng_datap pData)
124 {
125 mng_int32 iBpp;
126 mng_uint8p pRawx;
127 mng_uint8p pRawx_prev;
128 mng_uint8p pPriorx;
129 mng_int32 iX;
130
131 #ifdef MNG_SUPPORT_TRACE
132 MNG_TRACE (pData, MNG_FN_FILTER_AVERAGE, MNG_LC_START);
133 #endif
134
135 iBpp = pData->iFilterbpp;
136 pRawx = pData->pWorkrow + pData->iPixelofs;
137 pPriorx = pData->pPrevrow + pData->iPixelofs;
138 pRawx_prev = pData->pWorkrow + pData->iPixelofs;
139
140 #ifdef MNG_DECREMENT_LOOPS
141 for (iX = iBpp - 1; iX >= 0; iX--)
142 #else
143 for (iX = 0; iX < iBpp; iX++)
144 #endif
145 {
146 *pRawx = (mng_uint8)(*pRawx + ((*pPriorx) >> 1));
147 pRawx++;
148 pPriorx++;
149 }
150
151 for (iX = iBpp; iX < pData->iRowsize; iX++)
152 {
153 *pRawx = (mng_uint8)(*pRawx + ((*pRawx_prev + *pPriorx) >> 1));
154 pRawx++;
155 pPriorx++;
156 pRawx_prev++;
157 }
158
159 #ifdef MNG_SUPPORT_TRACE
160 MNG_TRACE (pData, MNG_FN_FILTER_AVERAGE, MNG_LC_END);
161 #endif
162
163 return MNG_NOERROR;
164 }
165
166 /* ************************************************************************** */
167
filter_paeth(mng_datap pData)168 MNG_LOCAL mng_retcode filter_paeth (mng_datap pData)
169 {
170 mng_int32 iBpp;
171 mng_uint8p pRawx;
172 mng_uint8p pRawx_prev;
173 mng_uint8p pPriorx;
174 mng_uint8p pPriorx_prev;
175 mng_int32 iX;
176 mng_uint32 iA, iB, iC;
177 mng_uint32 iP;
178 mng_uint32 iPa, iPb, iPc;
179
180 #ifdef MNG_SUPPORT_TRACE
181 MNG_TRACE (pData, MNG_FN_FILTER_PAETH, MNG_LC_START);
182 #endif
183
184 iBpp = pData->iFilterbpp;
185 pRawx = pData->pWorkrow + pData->iPixelofs;
186 pPriorx = pData->pPrevrow + pData->iPixelofs;
187 pRawx_prev = pData->pWorkrow + pData->iPixelofs;
188 pPriorx_prev = pData->pPrevrow + pData->iPixelofs;
189
190 #ifdef MNG_DECREMENT_LOOPS
191 for (iX = iBpp - 1; iX >= 0; iX--)
192 #else
193 for (iX = 0; iX < iBpp; iX++)
194 #endif
195 {
196 *pRawx = (mng_uint8)(*pRawx + *pPriorx);
197
198 pRawx++;
199 pPriorx++;
200 }
201
202 for (iX = iBpp; iX < pData->iRowsize; iX++)
203 {
204 iA = (mng_uint32)*pRawx_prev;
205 iB = (mng_uint32)*pPriorx;
206 iC = (mng_uint32)*pPriorx_prev;
207 iP = iA + iB - iC;
208 iPa = abs (iP - iA);
209 iPb = abs (iP - iB);
210 iPc = abs (iP - iC);
211
212 if ((iPa <= iPb) && (iPa <= iPc))
213 *pRawx = (mng_uint8)(*pRawx + iA);
214 else
215 if (iPb <= iPc)
216 *pRawx = (mng_uint8)(*pRawx + iB);
217 else
218 *pRawx = (mng_uint8)(*pRawx + iC);
219
220 pRawx++;
221 pPriorx++;
222 pRawx_prev++;
223 pPriorx_prev++;
224 }
225
226 #ifdef MNG_SUPPORT_TRACE
227 MNG_TRACE (pData, MNG_FN_FILTER_PAETH, MNG_LC_END);
228 #endif
229
230 return MNG_NOERROR;
231 }
232
233 /* ************************************************************************** */
234
mng_filter_a_row(mng_datap pData)235 mng_retcode mng_filter_a_row (mng_datap pData)
236 {
237 mng_retcode iRetcode;
238
239 #ifdef MNG_SUPPORT_TRACE
240 MNG_TRACE (pData, MNG_FN_FILTER_A_ROW, MNG_LC_START);
241 #endif
242
243 switch (*(pData->pWorkrow + pData->iFilterofs))
244 {
245 case 1 : {
246 iRetcode = filter_sub (pData);
247 break;
248 }
249 case 2 : {
250 iRetcode = filter_up (pData);
251 break;
252 }
253 case 3 : {
254 iRetcode = filter_average (pData);
255 break;
256 }
257 case 4 : {
258 iRetcode = filter_paeth (pData);
259 break;
260 }
261
262 default : iRetcode = MNG_INVALIDFILTER;
263 }
264
265 #ifdef MNG_SUPPORT_TRACE
266 MNG_TRACE (pData, MNG_FN_FILTER_A_ROW, MNG_LC_END);
267 #endif
268
269 return iRetcode;
270 }
271
272 /* ************************************************************************** */
273 /* ************************************************************************** */
274
275 #ifdef FILTER192
mng_init_rowdiffering(mng_datap pData)276 mng_retcode mng_init_rowdiffering (mng_datap pData)
277 {
278 mng_uint8p pRawi, pRawo;
279 mng_int32 iX;
280
281 #ifdef MNG_SUPPORT_TRACE
282 MNG_TRACE (pData, MNG_FN_INIT_ROWDIFFERING, MNG_LC_START);
283 #endif
284
285 if (pData->iFilter == 0xC0) /* has leveling parameters ? */
286 {
287 switch (pData->iColortype) /* salvage leveling parameters */
288 {
289 case 0 : { /* gray */
290 if (pData->iBitdepth <= 8)
291 pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
292 else
293 pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
294
295 break;
296 }
297 case 2 : { /* rgb */
298 if (pData->iBitdepth <= 8)
299 {
300 pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
301 pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
302 pData->iLevel2 = (mng_uint16)*(pData->pWorkrow+2);
303 }
304 else
305 {
306 pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
307 pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
308 pData->iLevel2 = mng_get_uint16 (pData->pWorkrow+4);
309 }
310
311 break;
312 }
313 case 3 : { /* indexed */
314 pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
315 break;
316 }
317 case 4 : { /* gray+alpha */
318 if (pData->iBitdepth <= 8)
319 {
320 pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
321 pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
322 }
323 else
324 {
325 pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
326 pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
327 }
328
329 break;
330 }
331 case 6 : { /* rgb+alpha */
332 if (pData->iBitdepth <= 8)
333 {
334 pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
335 pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
336 pData->iLevel2 = (mng_uint16)*(pData->pWorkrow+2);
337 pData->iLevel3 = (mng_uint16)*(pData->pWorkrow+3);
338 }
339 else
340 {
341 pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
342 pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
343 pData->iLevel2 = mng_get_uint16 (pData->pWorkrow+4);
344 pData->iLevel3 = mng_get_uint16 (pData->pWorkrow+6);
345 }
346
347 break;
348 }
349 }
350 }
351 /* shift the entire row back in place */
352 pRawi = pData->pWorkrow + pData->iFilterofs;
353 pRawo = pData->pWorkrow;
354
355 for (iX = 0; iX < pData->iRowsize + pData->iPixelofs - pData->iFilterofs; iX++)
356 *pRawo++ = *pRawi++;
357
358 pData->iFilterofs = 0; /* indicate so ! */
359
360 #ifdef FILTER193
361 if (pData->iFilter == 0xC1) /* no adaptive filtering ? */
362 pData->iPixelofs = pData->iFilterofs;
363 else
364 #endif
365 pData->iPixelofs = pData->iFilterofs + 1;
366
367 #ifdef MNG_SUPPORT_TRACE
368 MNG_TRACE (pData, MNG_FN_INIT_ROWDIFFERING, MNG_LC_END);
369 #endif
370
371 return MNG_NOERROR;
372 }
373
374 /* ************************************************************************** */
375
mng_differ_g1(mng_datap pData)376 mng_retcode mng_differ_g1 (mng_datap pData)
377 {
378 mng_uint8p pRawi, pRawo;
379 mng_int32 iX;
380
381 #ifdef MNG_SUPPORT_TRACE
382 MNG_TRACE (pData, MNG_FN_DIFFER_G1, MNG_LC_START);
383 #endif
384
385 if (pData->iLevel0 & 0x01) /* is it uneven level ? */
386 {
387 pRawi = pData->pWorkrow + pData->iPixelofs;
388 pRawo = pData->pPrevrow + pData->iPixelofs;
389 /* just invert every bit */
390 #ifdef MNG_DECREMENT_LOOPS
391 for (iX = pData->iRowsize - 1; iX >= 0; iX--)
392 #else
393 for (iX = 0; iX < pData->iRowsize; iX++)
394 #endif
395 *pRawo++ = (mng_uint8)(~(*pRawi++));
396
397 }
398
399 #ifdef MNG_SUPPORT_TRACE
400 MNG_TRACE (pData, MNG_FN_DIFFER_G1, MNG_LC_END);
401 #endif
402
403 return MNG_NOERROR;
404 }
405
406 /* ************************************************************************** */
407
mng_differ_g2(mng_datap pData)408 mng_retcode mng_differ_g2 (mng_datap pData)
409 {
410 mng_uint8p pRawi, pRawo;
411 mng_int32 iX;
412 mng_int32 iC, iS;
413 mng_uint8 iB, iN, iQ;
414
415 #ifdef MNG_SUPPORT_TRACE
416 MNG_TRACE (pData, MNG_FN_DIFFER_G2, MNG_LC_START);
417 #endif
418
419 pRawi = pData->pWorkrow + pData->iPixelofs;
420 pRawo = pData->pPrevrow + pData->iPixelofs;
421 iC = 0;
422 iB = 0;
423 iN = 0;
424 iS = 0;
425
426 #ifdef MNG_DECREMENT_LOOPS
427 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
428 #else
429 for (iX = 0; iX < pData->iRowsamples; iX++)
430 #endif
431 {
432 if (!iC)
433 {
434 iC = 4;
435 iB = *pRawi++;
436 iN = 0;
437 iS = 8;
438 }
439
440 iS -= 2;
441 iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x03);
442 iN = (mng_uint8)((iN << 2) + iQ);
443 iC--;
444
445 if (!iC)
446 *pRawo++ = iN;
447
448 }
449
450 if (iC)
451 *pRawo = (mng_uint8)(iN << iS);
452
453 #ifdef MNG_SUPPORT_TRACE
454 MNG_TRACE (pData, MNG_FN_DIFFER_G2, MNG_LC_END);
455 #endif
456
457 return MNG_NOERROR;
458 }
459
460 /* ************************************************************************** */
461
mng_differ_g4(mng_datap pData)462 mng_retcode mng_differ_g4 (mng_datap pData)
463 {
464 mng_uint8p pRawi, pRawo;
465 mng_int32 iX;
466 mng_int32 iC, iS;
467 mng_uint8 iB, iN, iQ;
468
469 #ifdef MNG_SUPPORT_TRACE
470 MNG_TRACE (pData, MNG_FN_DIFFER_G4, MNG_LC_START);
471 #endif
472
473 pRawi = pData->pWorkrow + pData->iPixelofs;
474 pRawo = pData->pPrevrow + pData->iPixelofs;
475 iC = 0;
476 iB = 0;
477 iN = 0;
478 iS = 0;
479
480 #ifdef MNG_DECREMENT_LOOPS
481 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
482 #else
483 for (iX = 0; iX < pData->iRowsamples; iX++)
484 #endif
485 {
486 if (!iC)
487 {
488 iC = 2;
489 iB = *pRawi++;
490 iN = 0;
491 iS = 8;
492 }
493
494 iS -= 4;
495 iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x0F);
496 iN = (mng_uint8)((iN << 4) + iQ);
497 iC--;
498
499 if (!iC)
500 *pRawo++ = iN;
501
502 }
503
504 if (iC)
505 *pRawo = (mng_uint8)(iN << iS);
506
507 #ifdef MNG_SUPPORT_TRACE
508 MNG_TRACE (pData, MNG_FN_DIFFER_G4, MNG_LC_END);
509 #endif
510
511 return MNG_NOERROR;
512 }
513
514 /* ************************************************************************** */
515
mng_differ_g8(mng_datap pData)516 mng_retcode mng_differ_g8 (mng_datap pData)
517 {
518 mng_uint8p pRawi, pRawo;
519 mng_int32 iX;
520
521 #ifdef MNG_SUPPORT_TRACE
522 MNG_TRACE (pData, MNG_FN_DIFFER_G8, MNG_LC_START);
523 #endif
524
525 pRawi = pData->pWorkrow + pData->iPixelofs;
526 pRawo = pData->pPrevrow + pData->iPixelofs;
527
528 #ifdef MNG_DECREMENT_LOOPS
529 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
530 #else
531 for (iX = 0; iX < pData->iRowsamples; iX++)
532 #endif
533 {
534 *pRawo++ = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
535
536 pRawi++;
537 }
538
539 #ifdef MNG_SUPPORT_TRACE
540 MNG_TRACE (pData, MNG_FN_DIFFER_G8, MNG_LC_END);
541 #endif
542
543 return MNG_NOERROR;
544 }
545
546 /* ************************************************************************** */
547
mng_differ_g16(mng_datap pData)548 mng_retcode mng_differ_g16 (mng_datap pData)
549 {
550 mng_uint16p pRawi, pRawo;
551 mng_int32 iX;
552
553 #ifdef MNG_SUPPORT_TRACE
554 MNG_TRACE (pData, MNG_FN_DIFFER_G16, MNG_LC_START);
555 #endif
556
557 pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
558 pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
559
560 #ifdef MNG_DECREMENT_LOOPS
561 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
562 #else
563 for (iX = 0; iX < pData->iRowsamples; iX++)
564 #endif
565 {
566 *pRawo++ = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0) & 0xFFFF);
567
568 pRawi++;
569 }
570
571 #ifdef MNG_SUPPORT_TRACE
572 MNG_TRACE (pData, MNG_FN_DIFFER_G16, MNG_LC_END);
573 #endif
574
575 return MNG_NOERROR;
576 }
577
578 /* ************************************************************************** */
579
mng_differ_rgb8(mng_datap pData)580 mng_retcode mng_differ_rgb8 (mng_datap pData)
581 {
582 mng_uint8p pRawi, pRawo;
583 mng_int32 iX;
584
585 #ifdef MNG_SUPPORT_TRACE
586 MNG_TRACE (pData, MNG_FN_DIFFER_RGB8, MNG_LC_START);
587 #endif
588
589 pRawi = pData->pWorkrow + pData->iPixelofs;
590 pRawo = pData->pPrevrow + pData->iPixelofs;
591
592 #ifdef MNG_DECREMENT_LOOPS
593 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
594 #else
595 for (iX = 0; iX < pData->iRowsamples; iX++)
596 #endif
597 {
598 *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
599 *pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0 +
600 (mng_uint16)*(pRawo+1)) & 0xFF);
601 *(pRawo+2) = (mng_uint8)(((mng_uint16)*(pRawi+2) + pData->iLevel2 +
602 (mng_uint16)*(pRawo+1)) & 0xFF);
603
604 pRawi += 3;
605 pRawo += 3;
606 }
607
608 #ifdef MNG_SUPPORT_TRACE
609 MNG_TRACE (pData, MNG_FN_DIFFER_RGB8, MNG_LC_END);
610 #endif
611
612 return MNG_NOERROR;
613 }
614
615 /* ************************************************************************** */
616
mng_differ_rgb16(mng_datap pData)617 mng_retcode mng_differ_rgb16 (mng_datap pData)
618 {
619 mng_uint16p pRawi, pRawo;
620 mng_int32 iX;
621
622 #ifdef MNG_SUPPORT_TRACE
623 MNG_TRACE (pData, MNG_FN_DIFFER_RGB16, MNG_LC_START);
624 #endif
625
626 pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
627 pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
628
629 #ifdef MNG_DECREMENT_LOOPS
630 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
631 #else
632 for (iX = 0; iX < pData->iRowsamples; iX++)
633 #endif
634 {
635 *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
636 *pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0 +
637 (mng_uint32)*(pRawo+1)) & 0xFFFF);
638 *(pRawo+2) = (mng_uint16)(((mng_uint32)*(pRawi+2) + (mng_uint32)pData->iLevel2 +
639 (mng_uint32)*(pRawo+1)) & 0xFFFF);
640
641 pRawi += 3;
642 pRawo += 3;
643 }
644
645 #ifdef MNG_SUPPORT_TRACE
646 MNG_TRACE (pData, MNG_FN_DIFFER_RGB16, MNG_LC_END);
647 #endif
648
649 return MNG_NOERROR;
650 }
651
652 /* ************************************************************************** */
653
mng_differ_idx1(mng_datap pData)654 mng_retcode mng_differ_idx1 (mng_datap pData)
655 {
656 mng_uint8p pRawi, pRawo;
657 mng_int32 iX;
658
659 #ifdef MNG_SUPPORT_TRACE
660 MNG_TRACE (pData, MNG_FN_DIFFER_IDX1, MNG_LC_START);
661 #endif
662
663 if (pData->iLevel0 & 0x01) /* is it uneven level ? */
664 {
665 pRawi = pData->pWorkrow + pData->iPixelofs;
666 pRawo = pData->pPrevrow + pData->iPixelofs;
667 /* just invert every bit */
668 #ifdef MNG_DECREMENT_LOOPS
669 for (iX = pData->iRowsize - 1; iX >= 0; iX--)
670 #else
671 for (iX = 0; iX < pData->iRowsize; iX++)
672 #endif
673 *pRawo++ = (mng_uint8)(~(*pRawi++));
674
675 }
676
677 #ifdef MNG_SUPPORT_TRACE
678 MNG_TRACE (pData, MNG_FN_DIFFER_IDX1, MNG_LC_END);
679 #endif
680
681 return MNG_NOERROR;
682 }
683
684 /* ************************************************************************** */
685
mng_differ_idx2(mng_datap pData)686 mng_retcode mng_differ_idx2 (mng_datap pData)
687 {
688 mng_uint8p pRawi, pRawo;
689 mng_int32 iX;
690 mng_int32 iC, iS;
691 mng_uint8 iB, iN, iQ;
692
693 #ifdef MNG_SUPPORT_TRACE
694 MNG_TRACE (pData, MNG_FN_DIFFER_IDX2, MNG_LC_START);
695 #endif
696
697 pRawi = pData->pWorkrow + pData->iPixelofs;
698 pRawo = pData->pPrevrow + pData->iPixelofs;
699 iC = 0;
700 iB = 0;
701 iN = 0;
702 iS = 0;
703
704 #ifdef MNG_DECREMENT_LOOPS
705 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
706 #else
707 for (iX = 0; iX < pData->iRowsamples; iX++)
708 #endif
709 {
710 if (!iC)
711 {
712 iC = 4;
713 iB = *pRawi++;
714 iN = 0;
715 iS = 8;
716 }
717
718 iS -= 2;
719 iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x03);
720 iN = (mng_uint8)((iN << 2) + iQ);
721 iC--;
722
723 if (!iC)
724 *pRawo++ = iN;
725
726 }
727
728 if (iC)
729 *pRawo = (mng_uint8)(iN << iS);
730
731 #ifdef MNG_SUPPORT_TRACE
732 MNG_TRACE (pData, MNG_FN_DIFFER_IDX2, MNG_LC_END);
733 #endif
734
735 return MNG_NOERROR;
736 }
737
738 /* ************************************************************************** */
739
mng_differ_idx4(mng_datap pData)740 mng_retcode mng_differ_idx4 (mng_datap pData)
741 {
742 mng_uint8p pRawi, pRawo;
743 mng_int32 iX;
744 mng_int32 iC, iS;
745 mng_uint8 iB, iN, iQ;
746
747 #ifdef MNG_SUPPORT_TRACE
748 MNG_TRACE (pData, MNG_FN_DIFFER_IDX4, MNG_LC_START);
749 #endif
750
751 pRawi = pData->pWorkrow + pData->iPixelofs;
752 pRawo = pData->pPrevrow + pData->iPixelofs;
753 iC = 0;
754 iB = 0;
755 iN = 0;
756 iS = 0;
757
758 #ifdef MNG_DECREMENT_LOOPS
759 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
760 #else
761 for (iX = 0; iX < pData->iRowsamples; iX++)
762 #endif
763 {
764 if (!iC)
765 {
766 iC = 2;
767 iB = *pRawi++;
768 iN = 0;
769 iS = 8;
770 }
771
772 iS -= 4;
773 iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x0F);
774 iN = (mng_uint8)((iN << 4) + iQ);
775 iC--;
776
777 if (!iC)
778 *pRawo++ = iN;
779
780 }
781
782 if (iC)
783 *pRawo = (mng_uint8)(iN << iS);
784
785 #ifdef MNG_SUPPORT_TRACE
786 MNG_TRACE (pData, MNG_FN_DIFFER_IDX4, MNG_LC_END);
787 #endif
788
789 return MNG_NOERROR;
790 }
791
792 /* ************************************************************************** */
793
mng_differ_idx8(mng_datap pData)794 mng_retcode mng_differ_idx8 (mng_datap pData)
795 {
796 mng_uint8p pRawi, pRawo;
797 mng_int32 iX;
798
799 #ifdef MNG_SUPPORT_TRACE
800 MNG_TRACE (pData, MNG_FN_DIFFER_IDX8, MNG_LC_START);
801 #endif
802
803 pRawi = pData->pWorkrow + pData->iPixelofs;
804 pRawo = pData->pPrevrow + pData->iPixelofs;
805
806 #ifdef MNG_DECREMENT_LOOPS
807 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
808 #else
809 for (iX = 0; iX < pData->iRowsamples; iX++)
810 #endif
811 {
812 *pRawo++ = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
813
814 pRawi++;
815 }
816
817 #ifdef MNG_SUPPORT_TRACE
818 MNG_TRACE (pData, MNG_FN_DIFFER_IDX8, MNG_LC_END);
819 #endif
820
821 return MNG_NOERROR;
822 }
823
824 /* ************************************************************************** */
825
mng_differ_ga8(mng_datap pData)826 mng_retcode mng_differ_ga8 (mng_datap pData)
827 {
828 mng_uint8p pRawi, pRawo;
829 mng_int32 iX;
830
831 #ifdef MNG_SUPPORT_TRACE
832 MNG_TRACE (pData, MNG_FN_DIFFER_GA8, MNG_LC_START);
833 #endif
834
835 pRawi = pData->pWorkrow + pData->iPixelofs;
836 pRawo = pData->pPrevrow + pData->iPixelofs;
837
838 #ifdef MNG_DECREMENT_LOOPS
839 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
840 #else
841 for (iX = 0; iX < pData->iRowsamples; iX++)
842 #endif
843 {
844 *pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
845 *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
846
847 pRawi += 2;
848 pRawo += 2;
849 }
850
851 #ifdef MNG_SUPPORT_TRACE
852 MNG_TRACE (pData, MNG_FN_DIFFER_GA8, MNG_LC_END);
853 #endif
854
855 return MNG_NOERROR;
856 }
857
858 /* ************************************************************************** */
859
mng_differ_ga16(mng_datap pData)860 mng_retcode mng_differ_ga16 (mng_datap pData)
861 {
862 mng_uint16p pRawi, pRawo;
863 mng_int32 iX;
864
865 #ifdef MNG_SUPPORT_TRACE
866 MNG_TRACE (pData, MNG_FN_DIFFER_GA16, MNG_LC_START);
867 #endif
868
869 pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
870 pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
871
872 #ifdef MNG_DECREMENT_LOOPS
873 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
874 #else
875 for (iX = 0; iX < pData->iRowsamples; iX++)
876 #endif
877 {
878 *pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0) & 0xFFFF);
879 *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
880
881 pRawi += 2;
882 }
883
884 #ifdef MNG_SUPPORT_TRACE
885 MNG_TRACE (pData, MNG_FN_DIFFER_GA16, MNG_LC_END);
886 #endif
887
888 return MNG_NOERROR;
889 }
890
891 /* ************************************************************************** */
892
mng_differ_rgba8(mng_datap pData)893 mng_retcode mng_differ_rgba8 (mng_datap pData)
894 {
895 mng_uint8p pRawi, pRawo;
896 mng_int32 iX;
897
898 #ifdef MNG_SUPPORT_TRACE
899 MNG_TRACE (pData, MNG_FN_DIFFER_RGBA8, MNG_LC_START);
900 #endif
901
902 pRawi = pData->pWorkrow + pData->iPixelofs;
903 pRawo = pData->pPrevrow + pData->iPixelofs;
904
905 #ifdef MNG_DECREMENT_LOOPS
906 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
907 #else
908 for (iX = 0; iX < pData->iRowsamples; iX++)
909 #endif
910 {
911 *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
912 *pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0 +
913 (mng_uint16)*(pRawo+1)) & 0xFF);
914 *(pRawo+2) = (mng_uint8)(((mng_uint16)*(pRawi+2) + pData->iLevel2 +
915 (mng_uint16)*(pRawo+1)) & 0xFF);
916 *(pRawo+3) = (mng_uint8)(((mng_uint16)*(pRawi+3) + pData->iLevel3) & 0xFF);
917
918 pRawi += 4;
919 pRawo += 4;
920 }
921
922 #ifdef MNG_SUPPORT_TRACE
923 MNG_TRACE (pData, MNG_FN_DIFFER_RGBA8, MNG_LC_END);
924 #endif
925
926 return MNG_NOERROR;
927 }
928
929 /* ************************************************************************** */
930
mng_differ_rgba16(mng_datap pData)931 mng_retcode mng_differ_rgba16 (mng_datap pData)
932 {
933 mng_uint16p pRawi, pRawo;
934 mng_int32 iX;
935
936 #ifdef MNG_SUPPORT_TRACE
937 MNG_TRACE (pData, MNG_FN_DIFFER_RGBA16, MNG_LC_START);
938 #endif
939
940 pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
941 pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
942
943 #ifdef MNG_DECREMENT_LOOPS
944 for (iX = pData->iRowsamples - 1; iX >= 0; iX--)
945 #else
946 for (iX = 0; iX < pData->iRowsamples; iX++)
947 #endif
948 {
949 *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
950 *pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0 +
951 (mng_uint32)*(pRawo+1)) & 0xFFFF);
952 *(pRawo+2) = (mng_uint16)(((mng_uint32)*(pRawi+2) + (mng_uint32)pData->iLevel2 +
953 (mng_uint32)*(pRawo+1)) & 0xFFFF);
954 *(pRawo+3) = (mng_uint16)(((mng_uint32)*(pRawi+3) + (mng_uint32)pData->iLevel3) & 0xFFFF);
955
956 pRawi += 4;
957 pRawo += 4;
958 }
959
960 #ifdef MNG_SUPPORT_TRACE
961 MNG_TRACE (pData, MNG_FN_DIFFER_RGBA16, MNG_LC_END);
962 #endif
963
964 return MNG_NOERROR;
965 }
966
967 /* ************************************************************************** */
968
969 #endif /* FILTER192 */
970
971 /* ************************************************************************** */
972
973 #endif /* MNG_INCLUDE_FILTERS */
974
975 /* ************************************************************************** */
976 /* * end of file * */
977 /* ************************************************************************** */
978
979