diff options
Diffstat (limited to 'prnt/hpijs/hpcupsfax.cpp')
-rw-r--r-- | prnt/hpijs/hpcupsfax.cpp | 779 |
1 files changed, 779 insertions, 0 deletions
diff --git a/prnt/hpijs/hpcupsfax.cpp b/prnt/hpijs/hpcupsfax.cpp new file mode 100644 index 0000000..350418c --- /dev/null +++ b/prnt/hpijs/hpcupsfax.cpp @@ -0,0 +1,779 @@ +/*****************************************************************************\ + hpcupsfax.cpp : HP CUPS fax filter + + Copyright (c) 2001 - 2010, Hewlett-Packard Co. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the Hewlett-Packard nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +\*****************************************************************************/ + +#include <sys/stat.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <syslog.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdint.h> +#include <time.h> +#include <sys/time.h> +#include <arpa/inet.h> +#include <math.h> +#include <cups/cups.h> +#include <cups/raster.h> +#include <string> +#ifdef FALSE +#undef FALSE +#endif +#ifdef TRUE +#undef TRUE +#endif +#include "hpip.h" +#include "hpcupsfax.h" +#include "bug.h" +using namespace std; + +int fax_encoding = RASTER_MMR; +char device_name[16]; +BYTE szFileHeader[68]; +BYTE szPageHeader[64]; + +uint32_t (*convert_endian_l)(uint32_t); +uint16_t (*convert_endian_s)(uint16_t); + +static int iLogLevel = 1; +char hpFileName[] = "/tmp/hplipfaxLog_XXXXXX"; + +#define TIFF_HDR_SIZE 8 +#define LITTLE_ENDIAN_MODE I +#define BIG_ENDIAN_MODE M + +#define DBG(args...) syslog(LOG_INFO, __FILE__ " " STRINGIZE(__LINE__) ": " args) + +// GrayLevel = (5/16)R + (9/16)G + (2/16)B +#define RGB2BW(r, g, b) (BYTE) (((r << 2) + r + (g << 3) + g + (b << 1)) >> 4) + +void RGB2Gray (BYTE *pRGBData, int iNumPixels, BYTE *pGData) +{ + int i; + BYTE *pIn = pRGBData; + BYTE *pOut = pGData; + for (i = 0; i < iNumPixels; i++, pIn += 3) + { + *pOut++ = RGB2BW ((unsigned short) *pIn, (unsigned short) pIn[1], (unsigned short) pIn[2]); + } +} + +static void GetLogLevel () +{ + FILE *fp; + char str[258]; + char *p; + fp = fopen ("/etc/cups/cupsd.conf", "r"); + if (fp == NULL) + return; + while (!feof (fp)) + { + if (!fgets (str, 256, fp)) + { + break; + } + if ((p = strstr (str, "hpLogLevel"))) + { + p += strlen ("hpLogLevel") + 1; + iLogLevel = atoi (p); + break; + } + } + fclose (fp); +} + +void PrintCupsHeader (cups_page_header2_t m_cupsHeader) +{ + if (iLogLevel == 0) + { + return; + } + BUG ("DEBUG: HPFAX - startPage...\n"); + BUG ("DEBUG: HPFAX - MediaClass = \"%s\"\n", m_cupsHeader.MediaClass); + BUG ("DEBUG: HPFAX - MediaColor = \"%s\"\n", m_cupsHeader.MediaColor); + BUG ("DEBUG: HPFAX - MediaType = \"%s\"\n", m_cupsHeader.MediaType); + BUG ("DEBUG: HPFAX - OutputType = \"%s\"\n", m_cupsHeader.OutputType); + BUG ("DEBUG: HPFAX - AdvanceDistance = %d\n", m_cupsHeader.AdvanceDistance); + BUG ("DEBUG: HPFAX - AdvanceMedia = %d\n", m_cupsHeader.AdvanceMedia); + BUG ("DEBUG: HPFAX - Collate = %d\n", m_cupsHeader.Collate); + BUG ("DEBUG: HPFAX - CutMedia = %d\n", m_cupsHeader.CutMedia); + BUG ("DEBUG: HPFAX - Duplex = %d\n", m_cupsHeader.Duplex); + BUG ("DEBUG: HPFAX - HWResolution = [ %d %d ]\n", m_cupsHeader.HWResolution[0], m_cupsHeader.HWResolution[1]); + BUG ("DEBUG: HPFAX - ImagingBoundingBox = [ %d %d %d %d ]\n", + m_cupsHeader.ImagingBoundingBox[0], m_cupsHeader.ImagingBoundingBox[1], + m_cupsHeader.ImagingBoundingBox[2], m_cupsHeader.ImagingBoundingBox[3]); + BUG ("DEBUG: HPFAX - InsertSheet = %d\n", m_cupsHeader.InsertSheet); + BUG ("DEBUG: HPFAX - Jog = %d\n", m_cupsHeader.Jog); + BUG ("DEBUG: HPFAX - LeadingEdge = %d\n", m_cupsHeader.LeadingEdge); + BUG ("DEBUG: HPFAX - Margins = [ %d %d ]\n", m_cupsHeader.Margins[0], m_cupsHeader.Margins[1]); + BUG ("DEBUG: HPFAX - ManualFeed = %d\n", m_cupsHeader.ManualFeed); + BUG ("DEBUG: HPFAX - MediaPosition = %d\n", m_cupsHeader.MediaPosition); + BUG ("DEBUG: HPFAX - MediaWeight = %d\n", m_cupsHeader.MediaWeight); + BUG ("DEBUG: HPFAX - MirrorPrint = %d\n", m_cupsHeader.MirrorPrint); + BUG ("DEBUG: HPFAX - NegativePrint = %d\n", m_cupsHeader.NegativePrint); + BUG ("DEBUG: HPFAX - NumCopies = %d\n", m_cupsHeader.NumCopies); + BUG ("DEBUG: HPFAX - Orientation = %d\n", m_cupsHeader.Orientation); + BUG ("DEBUG: HPFAX - OutputFaceUp = %d\n", m_cupsHeader.OutputFaceUp); + BUG ("DEBUG: HPFAX - PageSize = [ %d %d ]\n", m_cupsHeader.PageSize[0], m_cupsHeader.PageSize[1]); + BUG ("DEBUG: HPFAX - Separations = %d\n", m_cupsHeader.Separations); + BUG ("DEBUG: HPFAX - TraySwitch = %d\n", m_cupsHeader.TraySwitch); + BUG ("DEBUG: HPFAX - Tumble = %d\n", m_cupsHeader.Tumble); + BUG ("DEBUG: HPFAX - cupsWidth = %d\n", m_cupsHeader.cupsWidth); + BUG ("DEBUG: HPFAX - cupsHeight = %d\n", m_cupsHeader.cupsHeight); + BUG ("DEBUG: HPFAX - cupsMediaType = %d\n", m_cupsHeader.cupsMediaType); + BUG ("DEBUG: HPFAX - cupsRowStep = %d\n", m_cupsHeader.cupsRowStep); + BUG ("DEBUG: HPFAX - cupsBitsPerColor = %d\n", m_cupsHeader.cupsBitsPerColor); + BUG ("DEBUG: HPFAX - cupsBitsPerPixel = %d\n", m_cupsHeader.cupsBitsPerPixel); + BUG ("DEBUG: HPFAX - cupsBytesPerLine = %d\n", m_cupsHeader.cupsBytesPerLine); + BUG ("DEBUG: HPFAX - cupsColorOrder = %d\n", m_cupsHeader.cupsColorOrder); + BUG ("DEBUG: HPFAX - cupsColorSpace = %d\n", m_cupsHeader.cupsColorSpace); + BUG ("DEBUG: HPFAX - cupsCompression = %d\n", m_cupsHeader.cupsCompression); + BUG ("DEBUG: HPFAX - cupsPageSizeName = %s\n", m_cupsHeader.cupsPageSizeName); +} + +int GetPageSizeFromString(char *string) +{ + int iPageSize = atoi(string); + if(iPageSize == 0) + { + if(strcmp(string,"Letter") ==0){ + iPageSize = 1; + } + else if(strcmp(string,"A4") ==0){ + iPageSize = 2; + } + else if(strcmp(string,"Legal") ==0){ + iPageSize = 3; + } + else{ + DBG("hpcupsfax: GetPageSizeFromString:Default Page Size is taken,ensure it is ok.\n"); + iPageSize = 1; + } + } + DBG("hpcupsfax: GetPageSizeFromString: PageSize = %d\n",iPageSize); + return iPageSize; +} + +int ProcessRasterData (cups_raster_t *cups_raster, int fdFax) +{ + int status = 0; + unsigned int i; + int widthMMR; + int iInputBufSize; + BYTE *pThisScanLine; + LPBYTE pbOutputBuf = NULL; + LPBYTE pInputBuf = NULL; + IP_XFORM_SPEC xForm[3]; + IP_IMAGE_TRAITS traits; + IP_HANDLE hJob; + + BYTE *p; + cups_page_header2_t cups_header; + int iPageNum = 0; + int color_mode; + char *pDev; + unsigned int uiPageNum = 0; + + pDev = getenv ("DEVICE_URI"); + + while (cupsRasterReadHeader2 (cups_raster, &cups_header)) + { + iPageNum++; + if (iPageNum == 1) + { + PrintCupsHeader (cups_header); + color_mode = (cups_header.cupsRowStep == 0) ? HPLIPFAX_MONO : HPLIPFAX_COLOR; + if (color_mode == HPLIPFAX_COLOR) + { + fax_encoding = RASTER_JPEG; + } + memset (szFileHeader, 0, sizeof (szFileHeader)); + memcpy (szFileHeader, "hplip_g3", 8); + p = szFileHeader + 8; + *p++ = 1; // Version Number + HPLIPPUTINT32 (p, 0); p += 4; // Total number of pages in this job + HPLIPPUTINT16 (p, cups_header.HWResolution[0]); p += 2; + HPLIPPUTINT16 (p, cups_header.HWResolution[1]); p += 2; + BUG("ATOI Value = %d",atoi (cups_header.cupsPageSizeName)); + *p++ = GetPageSizeFromString(cups_header.cupsPageSizeName); // Output paper size + *p++ = atoi (cups_header.OutputType); // Output quality + *p++ = fax_encoding; // MH, MMR or JPEG + p += 4; // Reserved 1 + p += 4; // Reserved 2 + write (fdFax, szFileHeader, (p - szFileHeader)); + } + + widthMMR = (((cups_header.cupsWidth + 7) >> 3)) << 3; + +/* + * Devices in the HPFax2 category require fixed width of 2528 pixels. + * Example: LaserJet 2727 MFP + */ + + if (strcmp (device_name, "HPFax4") ==0) + { + widthMMR = 1728; + } + else if (!strcmp (device_name, "HPFax2")) + { + widthMMR = 2528; + } + iInputBufSize = widthMMR * cups_header.cupsHeight; + + pInputBuf = (LPBYTE) malloc (iInputBufSize); + if (pInputBuf == NULL) + { + BUG ("Unable to allocate pInputBuf, size = %d\n", iInputBufSize); + goto BUGOUT; + } + memset (pInputBuf, 0xFF, iInputBufSize); + + pThisScanLine = new BYTE[cups_header.cupsBytesPerLine]; + if (pThisScanLine == NULL) + { + BUG ("Unable to allocate pThisScanLine, size = %d\n", cups_header.cupsBytesPerLine); + goto BUGOUT; + } + + for (i = 0; i < cups_header.cupsHeight; i++) + { + cupsRasterReadPixels (cups_raster, pThisScanLine, cups_header.cupsBytesPerLine); + RGB2Gray (pThisScanLine, cups_header.cupsWidth, pInputBuf + i * widthMMR); + } + + WORD wResult; + DWORD dwInputAvail; + DWORD dwInputUsed; + DWORD dwInputNextPos; + DWORD dwOutputAvail; + DWORD dwOutputUsed; + DWORD dwOutputThisPos; + pbOutputBuf = (LPBYTE) malloc (iInputBufSize); + if (pbOutputBuf == NULL) + { + BUG ("unable to allocate pbOutputBuf, buffer size = %d\n", iInputBufSize); + goto BUGOUT; + } + memset (pbOutputBuf, 0xFF, iInputBufSize); + + memset (xForm, 0, sizeof (xForm)); + + if (color_mode == HPLIPFAX_MONO) + { + i = 0; + xForm[i].eXform = X_GRAY_2_BI; + + // 0 - Error diffusion + // >0 - Threshold value + + xForm[i].aXformInfo[IP_GRAY_2_BI_THRESHOLD].dword = 127; + i++; + + xForm[i].eXform = X_FAX_ENCODE; + if (fax_encoding== RASTER_MMR) + { + xForm[i].aXformInfo[IP_FAX_FORMAT].dword = IP_FAX_MMR; + } + else + { + xForm[i].aXformInfo[IP_FAX_FORMAT].dword = IP_FAX_MH; + } + /* 0 = EOLs are in data as usual; */ + /* 1 = no EOLs in data. */ + xForm[i].aXformInfo[IP_FAX_NO_EOLS].dword = 0; + xForm[i].pXform = NULL; + xForm[i].pfReadPeek = NULL; + xForm[i].pfWritePeek = NULL; + i++; + + wResult = ipOpen (i, xForm, 0, &hJob); + traits.iComponentsPerPixel = 1; + traits.iBitsPerPixel = 8; + } + else + { + xForm[0].eXform = X_CNV_COLOR_SPACE; + xForm[0].aXformInfo[IP_CNV_COLOR_SPACE_WHICH_CNV].dword = IP_CNV_SRGB_TO_YCC; + xForm[1].eXform = X_CNV_COLOR_SPACE; + xForm[1].aXformInfo[IP_CNV_COLOR_SPACE_WHICH_CNV].dword = IP_CNV_YCC_TO_CIELAB; + xForm[0].eXform = X_JPG_ENCODE; + xForm[0].aXformInfo[IP_JPG_ENCODE_FOR_COLOR_FAX].dword = 1; + wResult = ipOpen (1, xForm, 0, &hJob); + traits.iComponentsPerPixel = 3; + traits.iBitsPerPixel = 8; + } + + if (wResult != IP_DONE) + { + BUG ("ipOpen failed: wResult = %x\n", wResult); + goto BUGOUT; + } + traits.iPixelsPerRow = widthMMR; + traits.lHorizDPI = cups_header.HWResolution[0]; + traits.lVertDPI = cups_header.HWResolution[1]; + traits.lNumRows = cups_header.cupsHeight; + traits.iNumPages = 1; + traits.iPageNum = 1; + + wResult = ipSetDefaultInputTraits (hJob, &traits); + if (wResult != IP_DONE) + { + BUG ("ipSetDefaultInputTraits failed: wResult = %x\n", wResult); + wResult = ipClose (hJob); + goto BUGOUT; + } + dwInputAvail = iInputBufSize; + dwOutputAvail = dwInputAvail; + + wResult = ipConvert (hJob, dwInputAvail, pInputBuf, &dwInputUsed, + &dwInputNextPos, dwOutputAvail, pbOutputBuf, + &dwOutputUsed, &dwOutputThisPos); + + if (wResult == IP_FATAL_ERROR) + { + BUG ("ipConvert failed, wResult = %d\n", wResult); + goto BUGOUT; + } + if (iLogLevel > 0) + { + BUG ("dwInputAvail = %d dwInputUsed = %d dwOutputUsed = %d\n", + dwInputAvail, dwInputUsed, dwOutputUsed); + } + wResult = ipClose (hJob); + hJob = 0; + + uiPageNum++; + + p = szPageHeader; + HPLIPPUTINT32 (p, uiPageNum); p += 4; // Current page number + HPLIPPUTINT32 (p, widthMMR); p += 4; // Num of pixels per row + HPLIPPUTINT32 (p, cups_header.cupsHeight); p += 4; // Num of rows in this page + HPLIPPUTINT32 (p, dwOutputUsed); p += 4; // Size in bytes of encoded data + HPLIPPUTINT32 (p, 0); p += 4; // Thumbnail data size + HPLIPPUTINT32 (p, 0); p += 4; // Reserved for future use + write (fdFax, szPageHeader, (p - szPageHeader)); + write (fdFax, pbOutputBuf, dwOutputUsed); +/* + * Write the thumbnail data here + */ + + // Send this to fax handler + + free (pbOutputBuf); + free (pInputBuf); + free (pThisScanLine); + pbOutputBuf = NULL; + pInputBuf = NULL; + pThisScanLine = NULL; + + } /* end while (1) */ + + lseek (fdFax, 9, SEEK_SET); + HPLIPPUTINT32 ((szFileHeader + 9), uiPageNum); + write (fdFax, szFileHeader + 9, 4); + +BUGOUT: + if (pbOutputBuf) + { + free (pbOutputBuf); + } + + if (pInputBuf) + { + free (pInputBuf); + } + + return status; +} + +/* + * Return Zero if all the below are successful + * Reading from stdin into a temp file + * Getting the final file with HPLIP file and page headers + */ +int ProcessTiffData(int fromFD, int toFD) +{ + BYTE *p; + int fdTiff; + BYTE pTmp[4096]; + struct timeval tv; + fd_set fds; + int page_length; + unsigned int page_counter; + unsigned int current_ifd_start; + unsigned int *ifd_offset; + unsigned int next_ifd_offset; + unsigned short ifd_count; + bool big_endian = false; + int i, ret, len; + BYTE szTiffHeader[TIFF_HDR_SIZE]; + int bytes_written = 0; + int ret_status = 0; + int bytes_read = 0; + char hpTiffFileName[] = "/tmp/hpliptiffXXXXXX"; + long input_file_size = 0; + + fdTiff = mkstemp (hpTiffFileName); + if (fdTiff < 0) + { + BUG ("ERROR: Unable to open Fax output file - %s for writing\n", hpTiffFileName); + return 1; + } + + memset (szFileHeader, 0, sizeof (szFileHeader)); + memcpy (szFileHeader, "hplip_g3", 8); + p = szFileHeader + 8; + *p++ = 1; // Version Number + HPLIPPUTINT32 (p, 0); p += 4; // Total number of pages in this job + HPLIPPUTINT16 (p, 0); p += 2; //HWResolution[0] + HPLIPPUTINT16 (p, 0); p += 2; //HWResolution[0] + *p++ = atoi ("0"); // Output paper size (cupsPageSizeName) + *p++ = atoi ("0"); // Output quality (cups OutputType) + *p++ = fax_encoding; // MH, MMR or JPEG, TIFF + p += 4; // Reserved 1 + p += 4; // Reserved 2 + write (toFD, szFileHeader, (p - szFileHeader)); + + FD_ZERO(&fds); + FD_SET(fromFD, &fds); + tv.tv_sec = 0; + tv.tv_usec = 100 * 1000; //100 ms + i = 0; + + + len = read (fromFD, pTmp, 4096); + if (len > 0) { + DBG("hpcupsfax: read %d bytes from stdin", len); + write (fdTiff, pTmp, len); + bytes_written += len; + } else { + DBG("hpcupsfax: No data was available..."); + } + + while (i++ < 10) + { + memset (pTmp, 0, 4096); + ret = select(fromFD+1, &fds, NULL, NULL, &tv); + if (ret < 0) { + DBG("hpcupsfax: Timed out, Continue..."); + continue; + } + + if (FD_ISSET(fromFD, &fds)) { + DBG("hpcupsfax: Data is available"); + while(1) { + memset (pTmp, 0, 4096); + len = read (fromFD, pTmp, 4096); + DBG("hpcupsfax: read %d bytes from stdin", len); + if (len <= 0) { + DBG("hpcupsfax: No data was available, Continue..."); + break; //break from inner while() + } + write (fdTiff, pTmp, len); + bytes_written += len; + } + } + } + DBG("hpcupsfax: total bytes written to fdTiff is %d ", bytes_written); + input_file_size = bytes_written; + + ret = lseek (fdTiff, 0, SEEK_SET); + memset (szTiffHeader, 0, sizeof (TIFF_HDR_SIZE)); + ret = read (fdTiff, szTiffHeader, 8); + DBG("hpcupsfax: read %d bytes from fdTiff", ret); + ifd_offset = (unsigned int *) &(szTiffHeader[4]); + if (szTiffHeader[0] == 'M') { + DBG("hpcupsfax: it is big endian"); + big_endian = true; + *ifd_offset = ntohl(*ifd_offset); + } + DBG("hpcupsfax: ifd_offset is %d", *ifd_offset); + + current_ifd_start = 0; + page_counter = 0; + bytes_written = 0; +//WHILE + while(1) { + // Note down the number of tags + ret = lseek (fdTiff, *ifd_offset, SEEK_SET); + ret = read (fdTiff, &ifd_count, 2); + if (big_endian) { + ifd_count = ntohs(ifd_count); + } + DBG("hpcupsfax: read %d bytes from fdTiff; ifd count is %d", ret, ifd_count); + + // Read the end of IFD to check if there is another IFD following (for e.g., next page or image) + ret = lseek (fdTiff, (*ifd_offset+2+((ifd_count)*12)), SEEK_SET); + ret = read (fdTiff, &next_ifd_offset, 4); + if (big_endian) { + next_ifd_offset = ntohs(next_ifd_offset); + } + DBG("hpcupsfax: read %d bytes from fdTiff at %d; next ifd offset is %d", + ret, (*ifd_offset+2+((ifd_count)*12)), next_ifd_offset); + + // Increment the page counter + page_counter = page_counter + 1; + DBG("hpcupsfax: Current page_counter is %d", page_counter); + + // Write Tiff data for the current page (IFD) + page_length = next_ifd_offset-current_ifd_start; + DBG("hpcupsfax: page_length is %d ", page_length); + if (page_length <= 0) { + len = lseek (fdTiff, 0, SEEK_END); + page_length = len - current_ifd_start; + } + DBG("hpcupsfax: current_ifd_start=%d next_ifd_offset=%d total bytes are %d", current_ifd_start, next_ifd_offset, page_length); + + // Write HPLIP page header + p = szPageHeader; + HPLIPPUTINT32 (p, page_counter); p += 4; // Current page number + HPLIPPUTINT32 (p, 0); p += 4; // Num of pixels per row - It is ImageWidth for Tiff + HPLIPPUTINT32 (p, 0); p += 4; // Num of rows in this page - It is ImageLength for Tiff + HPLIPPUTINT32 (p, page_length); p += 4; // Size in bytes of encoded data + HPLIPPUTINT32 (p, 0); p += 4; // Thumbnail data size + HPLIPPUTINT32 (p, 0); p += 4; // Reserved for future use + ret = write (toFD, szPageHeader, (p - szPageHeader)); + + ret = lseek (fdTiff, current_ifd_start, SEEK_SET); + while (page_length > 0) { + if (page_length < 4096) { + len = page_length; + } else { + len = 4096; + } + bytes_read = read (fdTiff, pTmp, len); + ret = write (toFD, pTmp, bytes_read); + page_length = page_length - ret; + bytes_written += ret; + } + + // If there is no next IFD, break from the loop. Else, continue... + if (bytes_written > input_file_size) { + BUG("Error!! Bytes written to toFD is becoming more than input file size."); + ret_status = -1; + break; // while(1) for page counting + } + + if (next_ifd_offset == 0) { + break; // while(1) for page counting + } + current_ifd_start = *ifd_offset = next_ifd_offset; + } // while(1) for page counting + + lseek (toFD, 9, SEEK_SET); + HPLIPPUTINT32 ((szFileHeader + 9), page_counter); + write (toFD, szFileHeader + 9, 4); + + return ret_status; +} + + +int send_data_to_stdout(int fromFD) +{ + int iSize, i; + int len; + BYTE *pTmp = NULL; + + iSize = lseek (fromFD, 0, SEEK_END); + lseek (fromFD, 0, SEEK_SET); + + DBG("hpcupsfax: lseek(fromFD) returned %d", iSize); + if (iSize > 0) + { + pTmp = (BYTE *) malloc (iSize); + } + if (pTmp == NULL) + { + iSize = 1024; + pTmp = (BYTE *) malloc (iSize); + if (pTmp == NULL) + { + return 1; + } + } + + while ((len = read (fromFD, pTmp, iSize)) > 0) + { + write (STDOUT_FILENO, pTmp, len); + } + free (pTmp); + + return 0; +} + +int main (int argc, char **argv) +{ + int status = 0; + int fd = 0; + int fdFax = -1; + int i = 0; + FILE *fdTiff; + cups_raster_t *cups_raster; + ppd_file_t *ppd; + ppd_attr_t *attr; + ppd_attr_t *compression_attr; + + /*********** PROLOGUE ***********/ + + GetLogLevel(); + openlog("hpcupsfax", LOG_PID, LOG_DAEMON); + + if (argc < 6 || argc > 7) + { + BUG ("ERROR: %s job-id user title copies options [file]\n", *argv); + return 1; + } + + if (argc == 7) + { + if ((fd = open (argv[6], O_RDONLY)) == -1) + { + BUG ("ERROR: Unable to open raster file %s\n", argv[6]); + return 1; + } + } + + while (argv[i] != NULL) { + DBG("hpcupsfax: argv[%d] = %s\n", i, argv[i]); + i++; + } + + fdFax = mkstemp (hpFileName); + if (fdFax < 0) + { + BUG ("ERROR: Unable to open Fax output file - %s for writing\n", hpFileName); + return 1; + } + + /*********** MAIN ***********/ + + ppd = ppdOpenFile (getenv ("PPD")); + if (ppd == NULL) + { + BUG ("ERROR: Unable to open ppd file %s\n", getenv ("PPD")); + return 1; + } + if ((attr = ppdFindAttr (ppd, "cupsModelName", NULL)) == NULL || + (attr && attr->value == NULL)) + { + ppdClose (ppd); + BUG ("ERROR: Required cupsModelName is missing in ppd file\n"); + return 1; + } + + memset (device_name, 0, sizeof (device_name)); + strncpy (device_name, attr->value, 15); + + if ((attr = ppdFindAttr (ppd, "DefaultEncoding", NULL)) == NULL || + (attr && attr->value == NULL)) + { + ppdClose (ppd); + BUG ("ERROR: Required DefaultEncoding is missing in ppd file\n"); + return 1; + } + if (strstr(argv[5],"Encoding=MMR")) + { + fax_encoding = RASTER_MMR; + } + else if(strstr(argv[5],"Encoding=MH")) + { + fax_encoding = RASTER_MH; + } + else if (strstr(argv[5],"Encoding=Auto")) + { + BUG ("WARNING: AUTO is selected for Fax Encoding! Ensure this type is correct for the device"); + fax_encoding = RASTER_AUTO; + } + else if (strstr(argv[5],"Encoding=TIFF")) + { + fax_encoding = RASTER_TIFF; + } + else + { + if(strcmp(attr->value,"MH") == 0) { + fax_encoding = RASTER_MH; + } else if(strcmp(attr->value,"MMR") == 0){ + fax_encoding = RASTER_MMR; + }else if(strcmp(attr->value,"TIFF") ==0){ + fax_encoding = RASTER_TIFF; + }else if(strcmp(attr->value,"Auto") ==0){ + BUG ("WARNING: AUTO is selected for Fax Encoding! Ensure this type is correct for the device"); + fax_encoding = RASTER_AUTO; + } + } + if (fax_encoding < 0) { + BUG ("ERROR: Required DefaultEncoding is invalid in ppd file\n"); + return 1; + } + DBG("hpcupsfax: main: fax_encoding = %d \n", fax_encoding); + ppdClose (ppd); + + if (fax_encoding == RASTER_TIFF) + { + status = ProcessTiffData(fd, fdFax); + } else { + cups_raster = cupsRasterOpen (fd, CUPS_RASTER_READ); + if (cups_raster == NULL) + { + status = 1; + BUG ("cupsRasterOpen failed, fd = %d\n", fd); + goto EPILOGUE; + } + + status = ProcessRasterData (cups_raster, fdFax); + + cupsRasterClose (cups_raster); + } + + DBG("hpcupsfax: Send data to stdout \n"); + status = send_data_to_stdout(fdFax); + + /*********** EPILOGUE ***********/ +EPILOGUE: + if (fd != 0) + { + close (fd); + } + + if (fdFax > 0) + { + close (fdFax); + if (!(iLogLevel & SAVE_PCL_FILE)) + { + //Retain the intermediate file only if it is needed for debugging purpose. + unlink(hpFileName); + } + } + + return status; +} + |