You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
282 lines
6.0 KiB
282 lines
6.0 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
util.c
|
|
|
|
Abstract:
|
|
|
|
This file contains utilitarian functions for
|
|
the FAX TIFF library.
|
|
|
|
Environment:
|
|
|
|
WIN32 User Mode
|
|
|
|
Author:
|
|
|
|
Wesley Witt (wesw) 17-Feb-1996
|
|
|
|
--*/
|
|
|
|
#include "tifflibp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
|
|
INT
|
|
FindWhiteRun(
|
|
PBYTE pbuf,
|
|
INT startBit,
|
|
INT stopBit
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Find the next span of white pixels on the specified line
|
|
|
|
Arguments:
|
|
|
|
pbuf - Points to uncompressed pixel data for the current line
|
|
startBit - Starting bit index
|
|
stopBit - Last bit index
|
|
|
|
Return Value:
|
|
|
|
Length of the next run of white pixels
|
|
|
|
--*/
|
|
|
|
{
|
|
static const BYTE WhiteRuns[256] = {
|
|
|
|
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
|
|
INT run, bits, n;
|
|
|
|
pbuf += (startBit >> 3);
|
|
if ((bits = stopBit-startBit) <= 0)
|
|
return 0;
|
|
|
|
//
|
|
// Take care of the case where starting bit index is not a multiple of 8
|
|
//
|
|
|
|
if (n = (startBit & 7)) {
|
|
|
|
run = WhiteRuns[(*pbuf << n) & 0xff];
|
|
if (run > BYTEBITS-n)
|
|
run = BYTEBITS-n;
|
|
if (n+run < BYTEBITS)
|
|
return run;
|
|
bits -= run;
|
|
pbuf++;
|
|
|
|
} else
|
|
run = 0;
|
|
|
|
//
|
|
// Look for consecutive DWORD value = 0
|
|
//
|
|
|
|
if (bits >= DWORDBITS * 2) {
|
|
|
|
PDWORD pdw;
|
|
|
|
//
|
|
// Align to a DWORD boundary first
|
|
//
|
|
|
|
while ((DWORD_PTR) pbuf & 3) {
|
|
|
|
if (*pbuf != 0)
|
|
return run + WhiteRuns[*pbuf];
|
|
|
|
run += BYTEBITS;
|
|
bits -= BYTEBITS;
|
|
pbuf++;
|
|
}
|
|
|
|
pdw = (PDWORD) pbuf;
|
|
|
|
while (bits >= DWORDBITS && *pdw == 0) {
|
|
|
|
pdw++;
|
|
run += DWORDBITS;
|
|
bits -= DWORDBITS;
|
|
}
|
|
|
|
pbuf = (PBYTE) pdw;
|
|
}
|
|
|
|
//
|
|
// Look for consecutive BYTE value = 0
|
|
//
|
|
|
|
while (bits >= BYTEBITS) {
|
|
|
|
if (*pbuf != 0)
|
|
return run + WhiteRuns[*pbuf];
|
|
|
|
pbuf++;
|
|
run += BYTEBITS;
|
|
bits -= BYTEBITS;
|
|
}
|
|
|
|
//
|
|
// Count the number of white pixels in the last byte
|
|
//
|
|
|
|
if (bits > 0)
|
|
run += WhiteRuns[*pbuf];
|
|
|
|
return run;
|
|
}
|
|
|
|
|
|
INT
|
|
FindBlackRun(
|
|
PBYTE pbuf,
|
|
INT startBit,
|
|
INT stopBit
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Find the next span of black pixels on the specified line
|
|
|
|
Arguments:
|
|
|
|
pbuf - Points to uncompressed pixel data for the current line
|
|
startBit - Starting bit index
|
|
stopBit - Last bit index
|
|
|
|
Return Value:
|
|
|
|
Length of the next run of black pixels
|
|
|
|
--*/
|
|
|
|
{
|
|
static const BYTE BlackRuns[256] = {
|
|
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8
|
|
};
|
|
|
|
INT run, bits, n;
|
|
|
|
pbuf += (startBit >> 3);
|
|
if ((bits = stopBit-startBit) <= 0)
|
|
return 0;
|
|
|
|
//
|
|
// Take care of the case where starting bit index is not a multiple of 8
|
|
//
|
|
|
|
if (n = (startBit & 7)) {
|
|
|
|
run = BlackRuns[(*pbuf << n) & 0xff];
|
|
if (run > BYTEBITS-n)
|
|
run = BYTEBITS-n;
|
|
if (n+run < BYTEBITS)
|
|
return run;
|
|
bits -= run;
|
|
pbuf++;
|
|
|
|
} else
|
|
run = 0;
|
|
|
|
//
|
|
// Look for consecutive DWORD value = 0xffffffff
|
|
//
|
|
|
|
if (bits >= DWORDBITS * 2) {
|
|
|
|
PDWORD pdw;
|
|
|
|
//
|
|
// Align to a DWORD boundary first
|
|
//
|
|
|
|
while ((DWORD_PTR) pbuf & 3) {
|
|
|
|
if (*pbuf != 0xff)
|
|
return run + BlackRuns[*pbuf];
|
|
|
|
run += BYTEBITS;
|
|
bits -= BYTEBITS;
|
|
pbuf++;
|
|
}
|
|
|
|
pdw = (PDWORD) pbuf;
|
|
|
|
while (bits >= DWORDBITS && *pdw == 0xffffffff) {
|
|
|
|
pdw++;
|
|
run += DWORDBITS;
|
|
bits -= DWORDBITS;
|
|
}
|
|
|
|
pbuf = (PBYTE) pdw;
|
|
}
|
|
|
|
//
|
|
// Look for consecutive BYTE value = 0xff
|
|
//
|
|
|
|
while (bits >= BYTEBITS) {
|
|
|
|
if (*pbuf != 0xff)
|
|
return run + BlackRuns[*pbuf];
|
|
|
|
pbuf++;
|
|
run += BYTEBITS;
|
|
bits -= BYTEBITS;
|
|
}
|
|
|
|
//
|
|
// Count the number of white pixels in the last byte
|
|
//
|
|
|
|
if (bits > 0)
|
|
run += BlackRuns[*pbuf];
|
|
|
|
return run;
|
|
}
|