예제 #1
0
unsigned fipMemoryIO::read(void *buffer, unsigned size, unsigned count) const {
	return FreeImage_ReadMemory(buffer, size, count, _hmem);
}
예제 #2
0
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
    TIFF *faxTIFF = NULL;
    FIBITMAP *dib = NULL;
    FIMEMORY *memory = NULL;

    //int verbose = 0;
    int stretch = 0;
    int rows;
    float resX = 204.0;
    float resY = 196.0;

    uint32 xsize = G3_DEFAULT_WIDTH;
    int compression_in = COMPRESSION_CCITTFAX3;
    int fillorder_in = FILLORDER_LSB2MSB;
    uint32 group3options_in = 0;    // 1d-encoded
    uint32 group4options_in = 0;    // compressed
    int photometric_in = PHOTOMETRIC_MINISWHITE;

    if(handle==NULL) return NULL;

    try {
        // set default load options

        compression_in = COMPRESSION_CCITTFAX3;         // input is g3-encoded
        group3options_in &= ~GROUP3OPT_2DENCODING;      // input is 1d-encoded (g3 only)
        fillorder_in = FILLORDER_MSB2LSB;               // input has msb-to-lsb fillorder

        /*
          Original input-related fax2tiff options

          while ((c = getopt(argc, argv, "R:X:o:1234ABLMPUW5678abcflmprsuvwz?")) != -1) {
          switch (c) {
          // input-related options
          case '3':       // input is g3-encoded
          compression_in = COMPRESSION_CCITTFAX3;
          break;
          case '4':       // input is g4-encoded
          compression_in = COMPRESSION_CCITTFAX4;
          break;
          case 'U':       // input is uncompressed (g3 and g4)
          group3options_in |= GROUP3OPT_UNCOMPRESSED;
          group4options_in |= GROUP4OPT_UNCOMPRESSED;
          break;
          case '1':       // input is 1d-encoded (g3 only)
          group3options_in &= ~GROUP3OPT_2DENCODING;
          break;
          case '2':       // input is 2d-encoded (g3 only)
          group3options_in |= GROUP3OPT_2DENCODING;
          break;
          case 'P':   // input has not-aligned EOL (g3 only)
          group3options_in &= ~GROUP3OPT_FILLBITS;
          break;
          case 'A':       // input has aligned EOL (g3 only)
          group3options_in |= GROUP3OPT_FILLBITS;
          break;
          case 'W':       // input has 0 mean white
          photometric_in = PHOTOMETRIC_MINISWHITE;
          break;
          case 'B':       // input has 0 mean black
          photometric_in = PHOTOMETRIC_MINISBLACK;
          break;
          case 'L':       // input has lsb-to-msb fillorder
          fillorder_in = FILLORDER_LSB2MSB;
          break;
          case 'M':       // input has msb-to-lsb fillorder
          fillorder_in = FILLORDER_MSB2LSB;
          break;
          case 'R':       // input resolution
          resY = (float) atof(optarg);
          break;
          case 'X':       // input width
          xsize = (uint32) atoi(optarg);
          break;

          // output-related options
          case 's':       // stretch image by dup'ng scanlines
          stretch = 1;
          break;
          case 'v':       // -v for info
          verbose++;
          break;
          }
          }

        */

        // open a temporary memory buffer to save decoded scanlines
        memory = FreeImage_OpenMemory();
        if(!memory) throw FI_MSG_ERROR_MEMORY;

        // wrap the raw fax file
        faxTIFF = TIFFClientOpen("(FakeInput)", "w",
                                 // TIFFClientOpen() fails if we don't set existing value here
                                 NULL,
                                 _g3ReadProc, _g3WriteProc,
                                 _g3SeekProc, _g3CloseProc,
                                 _g3SizeProc, _g3MapProc,
                                 _g3UnmapProc);

        if (faxTIFF == NULL) {
            throw "Can not create fake input file";
        }
        TIFFSetMode(faxTIFF, O_RDONLY);
        TIFFSetField(faxTIFF, TIFFTAG_IMAGEWIDTH, xsize);
        TIFFSetField(faxTIFF, TIFFTAG_SAMPLESPERPIXEL, 1);
        TIFFSetField(faxTIFF, TIFFTAG_BITSPERSAMPLE, 1);
        TIFFSetField(faxTIFF, TIFFTAG_FILLORDER, fillorder_in);
        TIFFSetField(faxTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
        TIFFSetField(faxTIFF, TIFFTAG_PHOTOMETRIC, photometric_in);
        TIFFSetField(faxTIFF, TIFFTAG_YRESOLUTION, resY);
        TIFFSetField(faxTIFF, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);

        // NB: this must be done after directory info is setup
        TIFFSetField(faxTIFF, TIFFTAG_COMPRESSION, compression_in);
        if (compression_in == COMPRESSION_CCITTFAX3)
            TIFFSetField(faxTIFF, TIFFTAG_GROUP3OPTIONS, group3options_in);
        else if (compression_in == COMPRESSION_CCITTFAX4)
            TIFFSetField(faxTIFF, TIFFTAG_GROUP4OPTIONS, group4options_in);

        resX = 204;
        if (!stretch) {
            TIFFGetField(faxTIFF, TIFFTAG_YRESOLUTION, &resY);
        } else {
            resY = 196;
        }

        // decode the raw fax data
        rows = copyFaxFile(io, handle, faxTIFF, xsize, stretch, memory);
        if(rows <= 0) throw "Error when decoding raw fax file : check the decoder options";


        // allocate the output dib
        dib = FreeImage_Allocate(xsize, rows, 1);
        unsigned pitch = FreeImage_GetPitch(dib);
        uint32 linesize = TIFFhowmany8(xsize);

        // fill the bitmap structure ...
        // ... palette
        RGBQUAD *pal = FreeImage_GetPalette(dib);
        if(photometric_in == PHOTOMETRIC_MINISWHITE) {
            pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255;
            pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 0;
        } else {
            pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
            pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
        }
        // ... resolution
        FreeImage_SetDotsPerMeterX(dib, (unsigned)(resX/0.0254000 + 0.5));
        FreeImage_SetDotsPerMeterY(dib, (unsigned)(resY/0.0254000 + 0.5));

        // read the decoded scanline and fill the bitmap data
        FreeImage_SeekMemory(memory, 0, SEEK_SET);
        BYTE *bits = FreeImage_GetScanLine(dib, rows - 1);
        for(int k = 0; k < rows; k++) {
            FreeImage_ReadMemory(bits, linesize, 1, memory);
            bits -= pitch;
        }

        // free the TIFF wrapper
        TIFFClose(faxTIFF);

        // free the memory buffer
        FreeImage_CloseMemory(memory);

    } catch(const char *message) {
        if(memory) FreeImage_CloseMemory(memory);
        if(faxTIFF) TIFFClose(faxTIFF);
        if(dib) FreeImage_Unload(dib);
        FreeImage_OutputMessageProc(s_format_id, message);
        return NULL;
    }

    return dib;

}