static WORD tonemap_convert ( IP_XFORM_HANDLE hXform, DWORD dwInputAvail, /* in: # avail bytes in in-buf */ PBYTE pbInputBuf, /* in: ptr to in-buffer */ PDWORD pdwInputUsed, /* out: # bytes used from in-buf */ PDWORD pdwInputNextPos, /* out: file-pos to read from next */ DWORD dwOutputAvail, /* in: # avail bytes in out-buf */ PBYTE pbOutputBuf, /* in: ptr to out-buffer */ PDWORD pdwOutputUsed, /* out: # bytes written in out-buf */ PDWORD pdwOutputThisPos) /* out: file-pos to write the data */ { PTMAP_INST g; int nBytes; PBYTE pIn, pOut, pOutAfter; HANDLE_TO_PTR (hXform, g); /**** Check if we were told to flush ****/ if (pbInputBuf == NULL) { PRINT (_T("tonemap_convert: Told to flush.\n"), 0, 0); *pdwInputUsed = *pdwOutputUsed = 0; *pdwInputNextPos = g->dwInNextPos; *pdwOutputThisPos = g->dwOutNextPos; return IP_DONE; } /**** Output a Row ****/ nBytes = g->dwBytesPerRow; INSURE (dwInputAvail >= (DWORD)nBytes ); INSURE (dwOutputAvail >= (DWORD)nBytes); pIn = pbInputBuf; pOut = pbOutputBuf; pOutAfter = pOut + nBytes; if (g->traits.iBitsPerPixel == 8) { /* easiest case */ while (pOut < pOutAfter) { *pOut++ = g->tonemap[*pIn++]; } } else if (g->traits.iBitsPerPixel == 24) { if (g->bLumSpace) { /* easy case: 24-bit color in a luminance space */ while (pOut < pOutAfter) { *pOut = g->tonemap[*pIn]; pIn += 3; pOut += 3; } } else { /* 24-bit color in RGB */ int rv, gv, bv; int l_old, l_new, dl; while (pOut < pOutAfter) { rv = *pIn++; gv = *pIn++; bv = *pIn++; l_old = NTSC_LUMINANCE (rv, gv, bv); l_new = g->tonemap[l_old]; /* new luminance */ dl = l_new - l_old; rv += dl; gv += dl; bv += dl; if (rv > 255) rv = 255; else if (rv < 0) rv = 0; if (gv > 255) gv = 255; else if (gv < 0) gv = 0; if (bv > 255) bv = 255; else if (bv < 0) bv = 0; *pOut++ = (BYTE)rv; *pOut++ = (BYTE)gv; *pOut++ = (BYTE)bv; } } } else { /* 48 bits/pixel */ PWORD src = (PWORD)pIn; PWORD dst = (PWORD)pOut; PWORD dstAfter = (PWORD)pOutAfter; int rv, gv, bv; int l_old, l_old8, l_new1, l_new2, l_new, dl; while (dst < dstAfter) { rv = *src++; gv = *src++; bv = *src++; /* use linear interpolation between tonemap entries * to compute new luminance (l_new) */ l_old = g->bLumSpace ? rv : NTSC_LUMINANCE (rv, gv, bv); l_old8 = l_old >> 8; l_new1 = g->tonemap[l_old8]; l_new2 = l_old8<255 ? g->tonemap[l_old8+1] : l_new1; l_new = (l_new2-l_new1)*(l_old&0x00ff) + (l_new1<<8); dl = l_new - l_old; rv += dl; if (rv > 65535) rv = 65535; else if (rv < 0) rv = 0; if (! g->bLumSpace) { gv += dl; bv += dl; if (gv > 65535) gv = 65535; else if (gv < 0) gv = 0; if (bv > 65535) bv = 65535; else if (bv < 0) bv = 0; } *dst++ = (WORD)rv; *dst++ = (WORD)gv; *dst++ = (WORD)bv; } } *pdwInputUsed = nBytes; g->dwInNextPos += nBytes; *pdwInputNextPos = g->dwInNextPos; *pdwOutputUsed = nBytes; *pdwOutputThisPos = g->dwOutNextPos; g->dwOutNextPos += nBytes; g->dwRowsDone += 1; return IP_CONSUMED_ROW | IP_PRODUCED_ROW | IP_READY_FOR_DATA; fatal_error: return IP_FATAL_ERROR; }
FUNC_STATUS WORD fakeMono_convert ( IP_XFORM_HANDLE hXform, DWORD dwInputAvail, /* in: # avail bytes in in-buf */ PBYTE pbInputBuf, /* in: ptr to in-buffer */ PDWORD pdwInputUsed, /* out: # bytes used from in-buf */ PDWORD pdwInputNextPos, /* out: file-pos to read from next */ DWORD dwOutputAvail, /* in: # avail bytes in out-buf */ PBYTE pbOutputBuf, /* in: ptr to out-buffer */ PDWORD pdwOutputUsed, /* out: # bytes written in out-buf */ PDWORD pdwOutputThisPos) /* out: file-pos to write the data */ { PFMON_INST g; int nBytes; PBYTE pIn, pInAfter, pOut; unsigned rv, gv, bv; int gray; HANDLE_TO_PTR (hXform, g); /**** Check if we were told to flush ****/ if (pbInputBuf == NULL) { PRINT (_T("fakeMono_convert: Told to flush.\n"), 0, 0); *pdwInputUsed = *pdwOutputUsed = 0; *pdwInputNextPos = g->dwInNextPos; *pdwOutputThisPos = g->dwOutNextPos; return IP_DONE; } /**** Output a Row ****/ nBytes = g->dwBytesPerRow; INSURE (dwInputAvail >= (DWORD)nBytes ); INSURE (dwOutputAvail >= (DWORD)nBytes); pIn = pbInputBuf; pOut = pbOutputBuf; pInAfter = pIn + nBytes; if (g->iFakeDPI == 1) { // faking bi-level while (pIn < pInAfter) { rv = *pIn++; gv = *pIn++; bv = *pIn++; gray = NTSC_LUMINANCE (rv, gv, bv); gray = (gray >= 128) ? 255 : 0; *pOut++ = (BYTE)gray; *pOut++ = (BYTE)gray; *pOut++ = (BYTE)gray; } } else { // faking grayscale while (pIn < pInAfter) { rv = *pIn++; gv = *pIn++; bv = *pIn++; gray = NTSC_LUMINANCE (rv, gv, bv); *pOut++ = (BYTE)gray; *pOut++ = (BYTE)gray; *pOut++ = (BYTE)gray; } } *pdwInputUsed = nBytes; g->dwInNextPos += nBytes; *pdwInputNextPos = g->dwInNextPos; *pdwOutputUsed = nBytes; *pdwOutputThisPos = g->dwOutNextPos; g->dwOutNextPos += nBytes; g->dwRowsDone += 1; return IP_CONSUMED_ROW | IP_PRODUCED_ROW | IP_READY_FOR_DATA; fatal_error: return IP_FATAL_ERROR; }