1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408 |
- /*
- * SpanDSP - a series of DSP components for telephony
- *
- * t43_tests.c - ITU T.43 JBIG for grey and colour FAX image processing
- *
- * Written by Steve Underwood <steveu@coppice.org>
- *
- * Copyright (C) 2011, 2013 Steve Underwood
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- /*! \file */
- /*! \page t43_tests_page T.43 tests
- \section t43_tests_page_sec_1 What does it do
- */
- #if defined(HAVE_CONFIG_H)
- #include "config.h"
- #endif
- #include <stdlib.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <memory.h>
- #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
- #include "spandsp.h"
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- #include <tif_dir.h>
- #endif
- #define IN_FILE_NAME "../test-data/itu/tiff-fx/l04x_02x.tif"
- #define OUT_FILE_NAME "t43_tests_receive.tif"
- t43_decode_state_t t43;
- t85_decode_state_t t85;
- lab_params_t lab_param;
- int write_row = 0;
- typedef struct
- {
- uint8_t *buf;
- int ptr;
- } packer_t;
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- /* TIFF-FX related extensions to the tag set supported by libtiff */
- static const TIFFFieldInfo tiff_fx_tiff_field_info[] =
- {
- {TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, FIELD_CUSTOM, false, false, (char *) "Indexed"},
- {TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, FIELD_CUSTOM, false, false, (char *) "GlobalParametersIFD"},
- {TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, FIELD_CUSTOM, false, false, (char *) "ProfileType"},
- {TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, FIELD_CUSTOM, false, false, (char *) "FaxProfile"},
- {TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, FIELD_CUSTOM, false, false, (char *) "CodingMethods"},
- {TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, FIELD_CUSTOM, false, false, (char *) "VersionYear"},
- {TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, FIELD_CUSTOM, false, false, (char *) "ModeNumber"},
- {TIFFTAG_DECODE, TIFF_VARIABLE, TIFF_VARIABLE, TIFF_SRATIONAL, FIELD_CUSTOM, false, true, (char *) "Decode"},
- {TIFFTAG_IMAGEBASECOLOR, TIFF_VARIABLE, TIFF_VARIABLE, TIFF_SHORT, FIELD_CUSTOM, false, true, (char *) "ImageBaseColor"},
- {TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, FIELD_CUSTOM, false, false, (char *) "T82Options"},
- {TIFFTAG_STRIPROWCOUNTS, TIFF_VARIABLE, TIFF_VARIABLE, TIFF_LONG, FIELD_CUSTOM, false, true, (char *) "StripRowCounts"},
- {TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, FIELD_CUSTOM, false, false, (char *) "ImageLayer"},
- };
- static TIFFFieldArray tifffxFieldArray;
- static TIFFField tiff_fx_tiff_fields[] =
- {
- { TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "Indexed" },
- { TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, (char *) "GlobalParametersIFD", &tifffxFieldArray },
- { TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "ProfileType", NULL },
- { TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "FaxProfile", NULL },
- { TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "CodingMethods", NULL },
- { TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "VersionYear", NULL },
- { TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "ModeNumber", NULL },
- { TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, (char *) "Decode", NULL },
- { TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, (char *) "ImageBaseColor", NULL },
- { TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "T82Options", NULL },
- { TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, (char *) "StripRowCounts", NULL },
- { TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "ImageLayer", NULL },
- };
- static TIFFFieldArray tiff_fx_field_array = { tfiatOther, 0, 12, tiff_fx_tiff_fields };
- #endif
- typedef struct
- {
- TIFF *tif;
- int pre_compressed;
- uint32_t compressed_image_len;
- uint32_t image_width;
- uint32_t image_length;
- float x_resolution;
- float y_resolution;
- uint16_t resolution_unit;
- uint16_t bits_per_sample;
- uint16_t samples_per_pixel;
- uint16_t compression;
- uint16_t photometric;
- int16_t YCbCrSubsampleHoriz;
- int16_t YCbCrSubsampleVert;
- int16_t planar_config;
- int32_t tile_width;
- int32_t tile_length;
- uint8_t *colour_map;
- float lmin;
- float lmax;
- float amin;
- float amax;
- float bmin;
- float bmax;
- } meta_t;
- int write_file(meta_t *meta, int page, const uint8_t buf[]);
- int read_file(meta_t *meta, int page);
- int read_compressed_image(meta_t *meta, uint8_t **buf);
- int read_decompressed_image(meta_t *meta, uint8_t **buf);
- static int row_write_handler(void *user_data, const uint8_t buf[], size_t len)
- {
- packer_t *s;
- s = (packer_t *) user_data;
- memcpy(&s->buf[s->ptr], buf, len);
- s->ptr += len;
- return 0;
- }
- /*- End of function --------------------------------------------------------*/
- static int t85_comment_handler(void *user_data, const uint8_t buf[], size_t len)
- {
- if (buf)
- printf("Comment (%lu): %s\n", (unsigned long int) len, buf);
- else
- printf("Comment (%lu): ---\n", (unsigned long int) len);
- return 0;
- }
- /*- End of function --------------------------------------------------------*/
- static int row_read_handler(void *user_data, uint8_t row[], size_t len)
- {
- packer_t *s;
- s = (packer_t *) user_data;
- memcpy(row, &s->buf[s->ptr], len);
- s->ptr += len;
- return len;
- }
- /*- End of function --------------------------------------------------------*/
- int write_file(meta_t *meta, int page, const uint8_t buf[])
- {
- TIFF *tif;
- int off;
- int i;
- time_t now;
- struct tm *tm;
- char date_buf[50 + 1];
- int bytes_per_row;
- t85_encode_state_t t85;
- t43_encode_state_t t43;
- int out_buf_len;
- int out_len;
- int chunk_len;
- uint8_t *out_buf;
- uint8_t *out_buf2;
- packer_t packer;
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- toff_t diroff;
- #endif
- tif = meta->tif;
- TIFFSetField(tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
- TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, meta->image_width);
- /* libtiff requires IMAGELENGTH to be set before SAMPLESPERPIXEL,
- or StripOffsets and StripByteCounts will have SAMPLESPERPIXEL values */
- TIFFSetField(tif, TIFFTAG_IMAGELENGTH, meta->image_length);
- TIFFSetField(tif, TIFFTAG_COMPRESSION, meta->compression);
- TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, meta->bits_per_sample);
- TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, meta->samples_per_pixel);
- TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
- TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
- TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, meta->image_length);
- TIFFSetField(tif, TIFFTAG_XRESOLUTION, meta->x_resolution);
- TIFFSetField(tif, TIFFTAG_YRESOLUTION, meta->y_resolution);
- TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, meta->resolution_unit);
- TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, meta->photometric);
- if (meta->samples_per_pixel > 1 && (meta->YCbCrSubsampleHoriz || meta->YCbCrSubsampleVert))
- TIFFSetField(tif, TIFFTAG_YCBCRSUBSAMPLING, meta->YCbCrSubsampleHoriz, meta->YCbCrSubsampleVert);
- TIFFSetField(tif, TIFFTAG_SOFTWARE, "spandsp");
- TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "Test");
- time(&now);
- tm = localtime(&now);
- sprintf(date_buf,
- "%4d/%02d/%02d %02d:%02d:%02d",
- tm->tm_year + 1900,
- tm->tm_mon + 1,
- tm->tm_mday,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec);
- TIFFSetField(tif, TIFFTAG_DATETIME, date_buf);
- TIFFSetField(tif, TIFFTAG_MAKE, "soft-switch.org");
- TIFFSetField(tif, TIFFTAG_MODEL, "spandsp");
- TIFFSetField(tif, TIFFTAG_HOSTCOMPUTER, "i7.coppice.org");
- #if defined(SPANDSP_SUPPORT_TIFF_FX)
- /* Make space for this to be filled in later */
- TIFFSetField(tif, TIFFTAG_GLOBALPARAMETERSIFD, 0);
- #endif
- if (meta->pre_compressed)
- {
- if (TIFFWriteRawStrip(tif, 0, (tdata_t) buf, meta->compressed_image_len) < 0)
- printf("Error writing TIFF strip.\n");
- }
- else
- {
- switch (meta->compression)
- {
- case COMPRESSION_T85:
- packer.buf = (uint8_t *) buf;
- packer.ptr = 0;
- t85_encode_init(&t85, meta->image_width, meta->image_length, row_read_handler, &packer);
- //if (meta->compression == T4_COMPRESSION_T85_L0)
- // t85_encode_set_options(&t85, 256, -1, -1);
- out_len = 0;
- out_buf_len = 0;
- out_buf = NULL;
- do
- {
- if (out_buf_len < out_len + 50000)
- {
- out_buf_len += 50000;
- if ((out_buf2 = realloc(out_buf, out_buf_len)) == NULL)
- {
- if (out_buf)
- free(out_buf);
- return -1;
- }
- out_buf = out_buf2;
- }
- chunk_len = t85_encode_get(&t85, &out_buf[out_len], 50000);
- out_len += chunk_len;
- }
- while (chunk_len > 0);
- if (TIFFWriteRawStrip(tif, 0, out_buf, out_len) < 0)
- printf("Error writing TIFF strip.\n");
- t85_encode_release(&t85);
- free(out_buf);
- break;
- case COMPRESSION_T43:
- packer.buf = (uint8_t *) buf;
- packer.ptr = 0;
- t43_encode_init(&t43, meta->image_width, meta->image_length, row_read_handler, &packer);
- out_len = 0;
- out_buf_len = 0;
- out_buf = NULL;
- do
- {
- if (out_buf_len < out_len + 50000)
- {
- out_buf_len += 50000;
- if ((out_buf2 = realloc(out_buf, out_buf_len)) == NULL)
- {
- if (out_buf)
- free(out_buf);
- return -1;
- }
- out_buf = out_buf2;
- }
- chunk_len = t43_encode_get(&t43, &out_buf[out_len], 50000);
- out_len += chunk_len;
- }
- while (chunk_len > 0);
- if (TIFFWriteRawStrip(tif, 0, out_buf, out_len) < 0)
- printf("Error writing TIFF strip.\n");
- t43_encode_release(&t43);
- free(out_buf);
- break;
- default:
- bytes_per_row = TIFFScanlineSize(tif);
- for (off = 0, i = 0; i < meta->image_length; off += bytes_per_row, i++)
- {
- if (TIFFWriteScanline(tif, (tdata_t) &buf[off], i, 0) < 0)
- printf("Error writing TIFF scan line.\n");
- }
- break;
- }
- }
- if (!TIFFWriteDirectory(tif))
- printf("Failed to write directory.\n");
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- if (!TIFFCreateCustomDirectory(tif, &tiff_fx_field_array))
- {
- TIFFSetField(tif, TIFFTAG_PROFILETYPE, PROFILETYPE_G3_FAX);
- TIFFSetField(tif, TIFFTAG_FAXPROFILE, FAXPROFILE_F);
- TIFFSetField(tif, TIFFTAG_CODINGMETHODS, CODINGMETHODS_T4_1D | CODINGMETHODS_T4_2D | CODINGMETHODS_T6);
- TIFFSetField(tif, TIFFTAG_VERSIONYEAR, "1998");
- TIFFSetField(tif, TIFFTAG_MODENUMBER, 3);
- diroff = 0;
- if (!TIFFWriteCustomDirectory(tif, &diroff))
- printf("Failed to write custom directory.\n");
- if (!TIFFSetDirectory(tif, (tdir_t) page))
- printf("Failed to set directory.\n");
- if (!TIFFSetField(tif, TIFFTAG_GLOBALPARAMETERSIFD, diroff))
- printf("Failed to set global parameters IFD.\n");
- if (!TIFFWriteDirectory(tif))
- printf("Failed to write directory.\n");
- }
- #endif
- return 0;
- }
- /*- End of function --------------------------------------------------------*/
- int read_file(meta_t *meta, int page)
- {
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- static const char *tiff_fx_fax_profiles[] =
- {
- "???",
- "profile S",
- "profile F",
- "profile J",
- "profile C",
- "profile L",
- "profile M"
- };
- uint8_t parm8;
- uint16_t parm16;
- uint32_t parm32;
- float *fl_parms;
- char uu[10];
- char *u;
- toff_t diroff;
- #endif
- TIFF *tif;
- uint16_t *map_L;
- uint16_t *map_a;
- uint16_t *map_b;
- uint16_t *map_z;
- lab_params_t lab;
- int entries;
- int i;
- tif = meta->tif;
- printf("Read %d\n", page);
- if (!TIFFSetDirectory(tif, (tdir_t) page))
- {
- printf("Unable to set TIFF directory %d!\n", page);
- return -1;
- }
- meta->image_width = 0;
- TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &meta->image_width);
- meta->image_length = 0;
- TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &meta->image_length);
- meta->x_resolution = 200.0f;
- TIFFGetField(tif, TIFFTAG_XRESOLUTION, &meta->x_resolution);
- meta->y_resolution = 200.0f;
- TIFFGetField(tif, TIFFTAG_YRESOLUTION, &meta->y_resolution);
- meta->resolution_unit = RESUNIT_INCH;
- TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &meta->resolution_unit);
- meta->bits_per_sample = 0;
- TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &meta->bits_per_sample);
- meta->samples_per_pixel = 0;
- TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &meta->samples_per_pixel);
- meta->compression = 0;
- TIFFGetField(tif, TIFFTAG_COMPRESSION, &meta->compression);
- meta->photometric = 0;
- TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &meta->photometric);
- meta->YCbCrSubsampleHoriz = 0;
- meta->YCbCrSubsampleVert = 0;
- TIFFGetField(tif, TIFFTAG_YCBCRSUBSAMPLING, &meta->YCbCrSubsampleHoriz, &meta->YCbCrSubsampleVert);
- meta->planar_config = PLANARCONFIG_CONTIG;
- TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &meta->planar_config);
- meta->tile_width = 0;
- TIFFGetField(tif, TIFFTAG_TILEWIDTH, &meta->tile_width);
- meta->tile_length = 0;
- TIFFGetField(tif, TIFFTAG_TILELENGTH, &meta->tile_length);
- switch (meta->photometric)
- {
- case PHOTOMETRIC_ITULAB:
- meta->lmin = 0.0f;
- meta->lmax = 100.0f;
- meta->amin = -21760.0f/255.0f; // For 12 bit -348160.0f/4095.0f
- meta->amax = 21590.0f/255.0f; // For 12 bit 347990.0f/4095.0f
- meta->bmin = -19200.0f/255.0f; // For 12 bit -307200.0f/4095.0f
- meta->bmax = 31800.0f/255.0f; // For 12 bit 511800.0f/4095.0f
- break;
- default:
- meta->lmin = 0.0f;
- meta->lmax = 0.0f;
- meta->amin = 0.0f;
- meta->amax = 0.0f;
- meta->bmin = 0.0f;
- meta->bmax = 0.0f;
- break;
- }
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- if (TIFFGetField(tif, TIFFTAG_DECODE, &parm16, &fl_parms))
- {
- meta->lmin = fl_parms[0];
- meta->lmax = fl_parms[1];
- meta->amin = fl_parms[2];
- meta->amax = fl_parms[3];
- meta->bmin = fl_parms[4];
- meta->bmax = fl_parms[5];
- printf("Got decode tag %f %f %f %f %f %f\n", meta->lmin, meta->lmax, meta->amin, meta->amax, meta->bmin, meta->bmax);
- }
- #endif
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- printf("Trying to get global parameters\n");
- if (TIFFGetField(tif, TIFFTAG_GLOBALPARAMETERSIFD, &diroff))
- {
- printf("Got global parameters - %" PRIu64 "\n", (uint64_t) diroff);
- if (!TIFFReadCustomDirectory(tif, diroff, &tiff_fx_field_array))
- {
- printf("Failed to set global parameters IFD.\n");
- }
- else
- {
- if (TIFFGetField(tif, TIFFTAG_PROFILETYPE, &parm32))
- printf(" Profile type %u\n", parm32);
- if (TIFFGetField(tif, TIFFTAG_FAXPROFILE, &parm8))
- printf(" FAX profile %s (%u)\n", tiff_fx_fax_profiles[parm8], parm8);
- if (TIFFGetField(tif, TIFFTAG_CODINGMETHODS, &parm32))
- printf(" Coding methods 0x%x\n", parm32);
- if (TIFFGetField(tif, TIFFTAG_VERSIONYEAR, &u))
- {
- memcpy(uu, u, 4);
- uu[4] = '\0';
- printf(" Version year \"%s\"\n", uu);
- }
- if (TIFFGetField(tif, TIFFTAG_MODENUMBER, &parm8))
- printf(" Mode number %u\n", parm8);
- }
- TIFFSetDirectory(tif, (tdir_t) page);
- }
- if (TIFFGetField(tif, TIFFTAG_PROFILETYPE, &parm32))
- printf("Profile type %u\n", parm32);
- if (TIFFGetField(tif, TIFFTAG_FAXPROFILE, &parm8))
- printf("FAX profile %s (%u)\n", tiff_fx_fax_profiles[parm8], parm8);
- if (TIFFGetField(tif, TIFFTAG_CODINGMETHODS, &parm32))
- printf("Coding methods 0x%x\n", parm32);
- if (TIFFGetField(tif, TIFFTAG_VERSIONYEAR, &u))
- {
- memcpy(uu, u, 4);
- uu[4] = '\0';
- printf("Version year \"%s\"\n", uu);
- }
- if (TIFFGetField(tif, TIFFTAG_MODENUMBER, &parm8))
- printf("Mode number %u\n", parm8);
- if (TIFFGetField(tif, TIFFTAG_T82OPTIONS, &parm32))
- printf("T.82 options 0x%x\n", parm32);
- #endif
- map_L = NULL;
- map_a = NULL;
- map_b = NULL;
- map_z = NULL;
- if (TIFFGetField(tif, TIFFTAG_COLORMAP, &map_L, &map_a, &map_b, &map_z))
- {
- entries = 1 << meta->bits_per_sample;
- if ((meta->colour_map = malloc(3*entries)))
- {
- #if 0
- /* Sweep the colormap in the proper order */
- for (i = 0; i < entries; i++)
- {
- meta->colour_map[3*i] = (map_L[i] >> 8) & 0xFF;
- meta->colour_map[3*i + 1] = (map_a[i] >> 8) & 0xFF;
- meta->colour_map[3*i + 2] = (map_b[i] >> 8) & 0xFF;
- printf("Map %3d - %5d %5d %5d\n", i, meta->colour_map[3*i], meta->colour_map[3*i + 1], meta->colour_map[3*i + 2]);
- }
- #else
- /* Sweep the colormap in the order that seems to work for l04x_02x.tif */
- for (i = 0; i < entries; i++)
- {
- meta->colour_map[i] = (map_L[i] >> 8) & 0xFF;
- meta->colour_map[256 + i] = (map_a[i] >> 8) & 0xFF;
- meta->colour_map[2*256 + i] = (map_b[i] >> 8) & 0xFF;
- }
- #endif
- /* The default luminant is D50 */
- set_lab_illuminant(&lab_param, 96.422f, 100.000f, 82.521f);
- set_lab_gamut(&lab, 0, 100, -85, 85, -75, 125, false);
- lab_to_srgb(&lab, meta->colour_map, meta->colour_map, 256);
- for (i = 0; i < entries; i++)
- printf("Map %3d - %5d %5d %5d\n", i, meta->colour_map[3*i], meta->colour_map[3*i + 1], meta->colour_map[3*i + 2]);
- }
- }
- meta->tif = tif;
- return 0;
- }
- /*- End of function --------------------------------------------------------*/
- int read_compressed_image(meta_t *meta, uint8_t **buf)
- {
- int i;
- int len;
- int total_len;
- int read_len;
- int num_strips;
- uint8_t *data;
- num_strips = TIFFNumberOfStrips(meta->tif);
- for (i = 0, total_len = 0; i < num_strips; i++)
- {
- total_len += TIFFRawStripSize(meta->tif, i);
- }
- if ((data = malloc(total_len)) == NULL)
- return -1;
- for (i = 0, read_len = 0; i < num_strips; i++, read_len += len)
- {
- if ((len = TIFFReadRawStrip(meta->tif, i, &data[read_len], total_len - read_len)) < 0)
- {
- printf("TIFF read error.\n");
- return -1;
- }
- }
- *buf = data;
- return total_len;
- }
- /*- End of function --------------------------------------------------------*/
- int read_decompressed_image(meta_t *meta, uint8_t **buf)
- {
- int bytes_per_row;
- int x;
- int y;
- int xx;
- int yy;
- int xxx;
- int yyy;
- int i;
- int j;
- int result;
- int total_raw;
- int total_data;
- uint8_t *raw_buf;
- uint8_t *image_buf;
- t85_decode_state_t t85;
- t43_decode_state_t t43;
- packer_t pack;
- logging_state_t *logging;
- logging_state_t logging2;
- #if 0
- uint8_t *jpeg_table;
- uint32_t jpeg_table_len;
- tsize_t off;
- uint32_t w;
- uint32_t h;
- #endif
- image_buf = NULL;
- total_data = 0;
- switch (meta->compression)
- {
- case COMPRESSION_T85:
- bytes_per_row = (meta->image_width + 7)/8;
- total_data = meta->image_length*bytes_per_row;
- printf("Total decompressed data %d, %d per row\n", total_data, bytes_per_row);
- /* Read the image into memory. */
- if ((image_buf = malloc(total_data)) == NULL)
- {
- printf("Failed to allocated image buffer\n");
- return -1;
- }
- total_raw = read_compressed_image(meta, &raw_buf);
- t85_decode_init(&t85, row_write_handler, &pack);
- t85_decode_set_comment_handler(&t85, 1000, t85_comment_handler, NULL);
- logging = t85_decode_get_logging_state(&t85);
- span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- pack.buf = image_buf;
- pack.ptr = 0;
- result = t85_decode_put(&t85, raw_buf, total_raw);
- if (result == T4_DECODE_MORE_DATA)
- result = t85_decode_put(&t85, NULL, 0);
- total_data = t85_decode_get_compressed_image_size(&t85);
- printf("Compressed image is %d/%d bytes, %d rows\n", total_raw, total_data/8, write_row);
- t85_decode_release(&t85);
- free(raw_buf);
- break;
- case COMPRESSION_T43:
- bytes_per_row = meta->samples_per_pixel*meta->image_width;
- total_data = meta->image_length*bytes_per_row;
- printf("Total decompressed data %d, %d per row\n", total_data, bytes_per_row);
- total_data *= 8;
- /* Read the image into memory. */
- if ((image_buf = malloc(total_data)) == NULL)
- printf("Failed to allocated image buffer\n");
- total_raw = read_compressed_image(meta, &raw_buf);
- t43_decode_init(&t43, row_write_handler, &pack);
- t43_decode_set_comment_handler(&t43, 1000, t85_comment_handler, NULL);
- logging = t43_decode_get_logging_state(&t43);
- span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- pack.buf = image_buf;
- pack.ptr = 0;
- result = t43_decode_put(&t43, raw_buf, total_raw);
- if (result == T4_DECODE_MORE_DATA)
- result = t43_decode_put(&t43, NULL, 0);
- t43_decode_release(&t43);
- free(raw_buf);
- meta->samples_per_pixel = 1;
- meta->photometric = PHOTOMETRIC_RGB;
- printf("Image %d x %d pixels\n", meta->image_width, meta->image_length);
- break;
- case COMPRESSION_JPEG:
- if (meta->photometric == PHOTOMETRIC_ITULAB)
- {
- printf(" ITULAB");
- span_log_init(&logging2, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW, "lab");
- bytes_per_row = TIFFScanlineSize(meta->tif);
- total_data = meta->image_length*bytes_per_row;
- printf("Total decompressed data %d, %d per row\n", total_data, bytes_per_row);
- /* Read the image into memory. */
- if ((image_buf = malloc(total_data)) == NULL)
- printf("Failed to allocated image buffer\n");
- #if 0
- jpeg_table_len = 0;
- if (TIFFGetField(meta->tif, TIFFTAG_JPEGTABLES, &jpeg_table_len, &jpeg_table))
- {
- total_image_len += (jpeg_table_len - 4);
- printf("JPEG tables %u\n", jpeg_table_len);
- {
- int ii;
- printf("YYY1 %d - ", jpeg_table_len);
- for (ii = 0; ii < jpeg_table_len; ii++)
- printf(" %02x", jpeg_table[ii]);
- printf("\n");
- }
- }
- #endif
- total_raw = read_compressed_image(meta, &raw_buf);
- //if (!t42_itulab_jpeg_to_srgb(&logging2, &lab_param, (tdata_t) image_buf, &off, raw_buf, total_raw, &w, &h, &samples_per_pixel))
- {
- printf("Failed to convert from ITULAB.\n");
- return 1;
- }
- meta->photometric = PHOTOMETRIC_RGB;
- #if 0
- total_len = 0;
- if (jpeg_table_len > 0)
- total_len += jpeg_table_len - 4;
- printf("nstrips %d\n", nstrips);
- data2 = NULL;
- for (i = 0; i < nstrips; i++, total_len += len)
- {
- total_len = 0;
- if (jpeg_table_len > 0)
- total_len += jpeg_table_len - 4;
- if ((len = TIFFReadRawStrip(tif, i, &data[total_len], total_image_len - total_len)) < 0)
- {
- printf("TIFF read error.\n");
- return -1;
- }
- if (jpeg_table_len > 0)
- {
- memcpy(data, jpeg_table, jpeg_table_len - 2);
- printf("%02x %02x %02x %02x\n", data[total_len], data[total_len + 1], data[total_len + 2], data[total_len + 3]);
- }
- totdata = meta->image_width*3000*meta->samples_per_pixel;
- data2 = realloc(data2, totdata);
- off = total_len;
- if (!t42_itulab_jpeg_to_srgb(&logging2, &lab_param, data2, &off, data, off, &w, &h, &samples_per_pixel))
- {
- printf("Failed to convert from ITULAB.\n");
- return 1;
- }
- }
- if (data2)
- free(data2);
- //exit(2);
- if (jpeg_table_len > 0)
- memcpy(data, jpeg_table, jpeg_table_len - 2);
- if (total_len != total_image_len)
- printf("Size mismatch %d %d\n", (int) total_len, (int) total_image_len);
- {
- int ii;
- printf("YYY2 %d - ", jpeg_table_len);
- for (ii = 0; ii < 800; ii++)
- printf(" %02x", data[ii]);
- printf("\n");
- }
- off = total_len;
- len = total_len;
- #endif
- break;
- }
- /* Fall through */
- default:
- if (meta->tile_width > 0)
- {
- /* The image is tiled, so we need to patch together a bunch of tiles */
- switch (meta->planar_config)
- {
- case PLANARCONFIG_CONTIG:
- bytes_per_row = TIFFScanlineSize(meta->tif);
- total_data = meta->image_length*bytes_per_row;
- printf("Total decompressed data %d, %d per row\n", total_data, bytes_per_row);
- /* Read the image into memory. */
- if ((image_buf = malloc(total_data)) == NULL)
- printf("Failed to allocated image buffer\n");
- for (y = 0; y < meta->image_length; y += meta->tile_length)
- {
- for (x = 0; x < meta->image_width; x += meta->tile_width)
- {
- uint8_t data[meta->tile_width*meta->tile_length*meta->samples_per_pixel];
- TIFFReadTile(meta->tif, data, x, y, 0, 0);
- yyy = meta->tile_length;
- if (y + meta->tile_length > meta->image_length)
- yyy = meta->image_length - y;
- xxx = meta->tile_width;
- if (x + meta->tile_width > meta->image_width)
- xxx = meta->image_width - x;
- for (yy = 0; yy < yyy; yy++)
- {
- for (xx = 0; xx < xxx; xx++)
- {
- for (j = 0; j < meta->samples_per_pixel; j++)
- image_buf[meta->samples_per_pixel*((y + yy)*meta->image_width + x + xx) + j] = data[meta->samples_per_pixel*(yy*meta->tile_width + xx) + j];
- }
- }
- }
- }
- break;
- case PLANARCONFIG_SEPARATE:
- bytes_per_row = TIFFScanlineSize(meta->tif);
- total_data = meta->samples_per_pixel*meta->image_length*bytes_per_row;
- printf("Total decompressed data %d, %d per row\n", total_data, bytes_per_row);
- /* Read the image into memory. */
- if ((image_buf = malloc(total_data)) == NULL)
- printf("Failed to allocated image buffer\n");
- for (j = 0; j < meta->samples_per_pixel; j++)
- {
- for (y = 0; y < meta->image_length; y += meta->tile_length)
- {
- for (x = 0; x < meta->image_width; x += meta->tile_width)
- {
- uint8_t data[meta->tile_width*meta->tile_length*meta->samples_per_pixel];
- TIFFReadTile(meta->tif, data, x, y, 0, j);
- yyy = meta->tile_length;
- if (y + meta->tile_length > meta->image_length)
- yyy = meta->image_length - y;
- xxx = meta->tile_width;
- if (x + meta->tile_width > meta->image_width)
- xxx = meta->image_width - x;
- for (yy = 0; yy < yyy; yy++)
- {
- for (xx = 0; xx < xxx; xx++)
- {
- image_buf[meta->samples_per_pixel*((y + yy)*meta->image_width + x + xx) + j] = data[yy*meta->tile_width + xx];
- }
- }
- }
- }
- }
- break;
- }
- }
- else
- {
- /* There is no tiling to worry about, but we might have planar issues to resolve */
- switch (meta->planar_config)
- {
- case PLANARCONFIG_CONTIG:
- bytes_per_row = TIFFScanlineSize(meta->tif);
- total_data = meta->image_length*bytes_per_row;
- printf("Total decompressed data %d, %d per row\n", total_data, bytes_per_row);
- /* Read the image into memory. */
- if ((image_buf = malloc(total_data)) == NULL)
- printf("Failed to allocated image buffer\n");
- for (y = 0; y < meta->image_length; y++)
- {
- if (TIFFReadScanline(meta->tif, &image_buf[y*bytes_per_row], y, 0) < 0)
- return 1;
- }
- break;
- case PLANARCONFIG_SEPARATE:
- bytes_per_row = TIFFScanlineSize(meta->tif);
- total_data = meta->samples_per_pixel*meta->image_length*bytes_per_row;
- printf("Total decompressed data %d, %d per row\n", total_data, bytes_per_row);
- /* Read the image into memory. */
- if ((image_buf = malloc(total_data)) == NULL)
- printf("Failed to allocated image buffer\n");
- for (j = 0; j < meta->samples_per_pixel; j++)
- {
- uint8_t data[bytes_per_row];
- for (y = 0; y < meta->image_length; y++)
- {
- if (TIFFReadScanline(meta->tif, data, y, j) < 0)
- return 1;
- for (x = 0; x < meta->image_width; x++)
- image_buf[meta->samples_per_pixel*(y*bytes_per_row + x) + j] = data[x];
- }
- }
- break;
- }
- }
- break;
- }
- /* Normalise bi-level images, so they are always in PHOTOMETRIC_MINISWHITE form */
- if (image_buf && meta->samples_per_pixel == 1 && meta->bits_per_sample == 1)
- {
- if (meta->photometric != PHOTOMETRIC_MINISWHITE)
- {
- for (i = 0; i < total_data; i++)
- image_buf[i] = ~image_buf[i];
- meta->photometric = PHOTOMETRIC_MINISWHITE;
- }
- }
- *buf = image_buf;
- return total_data;
- }
- /*- End of function --------------------------------------------------------*/
- int main(int argc, char *argv[])
- {
- const char *source_file;
- const char *destination_file;
- TIFF *tif;
- tstrip_t nstrips;
- uint32_t totdata;
- tsize_t off;
- uint8_t *data;
- uint8_t *data2;
- int row;
- int bytes_per_row;
- tsize_t outsize;
- char *outptr;
- int i;
- int k;
- int x;
- int y;
- uint64_t start;
- uint64_t end;
- logging_state_t logging2;
- meta_t in_meta;
- meta_t meta;
- int output_compression;
- int page_no;
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- toff_t diroff;
- #endif
- source_file = (argc > 1) ? argv[1] : IN_FILE_NAME;
- printf("Processing '%s'\n", source_file);
- destination_file = OUT_FILE_NAME;
- output_compression = (argc > 2) ? atoi(argv[2]) : COMPRESSION_CCITT_T6;
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- TIFF_FX_init();
- #endif
- if ((in_meta.tif = TIFFOpen(source_file, "r")) == NULL)
- {
- printf("Unable to open '%s'!\n", source_file);
- return 1;
- }
- if ((meta.tif = TIFFOpen(destination_file, "w")) == NULL)
- {
- printf("Unable to open '%s'!\n", destination_file);
- return 1;
- }
- span_log_init(&logging2, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW, "lab");
- /* The default luminant is D50 */
- set_lab_illuminant(&lab_param, 96.422f, 100.000f, 82.521f);
- set_lab_gamut(&lab_param, 0, 100, -85, 85, -75, 125, false);
- outptr = NULL;
- for (page_no = 0; ; page_no++)
- {
- if (read_file(&in_meta, page_no) < 0)
- {
- printf("Failed to read from %s\n", source_file);
- TIFFClose(in_meta.tif);
- TIFFClose(meta.tif);
- exit(2);
- }
- tif = in_meta.tif;
- nstrips = TIFFNumberOfStrips(tif);
- if (in_meta.compression == output_compression && nstrips == 1 && in_meta.tile_width == 0)
- {
- /* There might be no need to re-compress the image */
- }
- else
- {
- /* It looks like we need to decompress and recompress the image */
- }
- printf("Width %d, height %d, bits %d, samples %d\n", in_meta.image_width, in_meta.image_length, in_meta.bits_per_sample, in_meta.samples_per_pixel);
- totdata = read_decompressed_image(&in_meta, &data);
- off = totdata;
- bytes_per_row = TIFFScanlineSize(tif);
- printf("bits_per_sample %d, samples_per_pixel %d, w %d, h %d\n", in_meta.bits_per_sample, in_meta.samples_per_pixel, in_meta.image_width, in_meta.image_length);
- printf("total %d, off %d\n", totdata, (int) off);
- switch (in_meta.samples_per_pixel)
- {
- case 1:
- if (in_meta.bits_per_sample == 1)
- {
- printf("Bi-level\n");
- /* We have finished acquiring the image. Now we need to push it out */
- meta.pre_compressed = false;
- meta.image_width = in_meta.image_width;
- meta.image_length = in_meta.image_length;
- meta.x_resolution = in_meta.x_resolution;
- meta.y_resolution = in_meta.y_resolution;
- meta.resolution_unit = in_meta.resolution_unit;
- meta.bits_per_sample = in_meta.bits_per_sample;
- meta.samples_per_pixel = in_meta.samples_per_pixel;
- meta.compression = COMPRESSION_CCITT_T6;
- meta.photometric = PHOTOMETRIC_MINISWHITE;
- write_file(&meta, page_no, data);
- }
- else
- {
- printf("Gray scale, %d bits\n", in_meta.bits_per_sample);
- if (in_meta.bits_per_sample == 8)
- {
- /* Nothing needs to be done */
- }
- else if (in_meta.bits_per_sample == 16)
- {
- if ((outptr = malloc(in_meta.image_width*in_meta.image_length)) == NULL)
- printf("Failed to allocate buffer\n");
- for (i = 0; i < in_meta.image_width*in_meta.image_length; i++)
- outptr[i] = data[2*i];
- free(data);
- data = (uint8_t *) outptr;
- }
- else
- {
- uint32_t bitstream;
- int bits;
- int j;
- /* Deal with the messy cases where the number of bits is not a whole
- number of bytes. */
- if ((outptr = malloc(in_meta.image_width*in_meta.image_length)) == NULL)
- printf("Failed to allocate buffer\n");
- bitstream = 0;
- bits = 0;
- j = 0;
- for (i = 0; i < in_meta.image_width*in_meta.image_length; i++)
- {
- while (bits < in_meta.bits_per_sample)
- {
- bitstream = (bitstream << 8) | data[j++];
- bits += 8;
- }
- outptr[i] = bitstream >> (bits - 8);
- bits -= in_meta.bits_per_sample;
- }
- free(data);
- data = (uint8_t *) outptr;
- }
- off = in_meta.samples_per_pixel*in_meta.image_width*in_meta.image_length;
- /* We have finished acquiring the image. Now we need to push it out */
- meta.pre_compressed = false;
- meta.image_width = in_meta.image_width;
- meta.image_length = in_meta.image_length;
- meta.x_resolution = in_meta.x_resolution;
- meta.y_resolution = in_meta.y_resolution;
- meta.resolution_unit = in_meta.resolution_unit;
- meta.bits_per_sample = 8;
- meta.samples_per_pixel = in_meta.samples_per_pixel;
- meta.compression = COMPRESSION_JPEG;
- meta.photometric = PHOTOMETRIC_MINISBLACK;
- write_file(&meta, page_no, data);
- }
- break;
- case 3:
- printf("Photometric is %d\n", in_meta.photometric);
- /* We now have the image in memory in RGB form */
- if (in_meta.photometric == PHOTOMETRIC_ITULAB)
- {
- printf("ITU Lab\n");
- /* We are already in the ITULAB color space */
- if ((outptr = malloc(totdata)) == NULL)
- printf("Failed to allocate buffer\n");
- lab_to_srgb(&lab_param, (tdata_t) outptr, data, totdata/3);
- free(data);
- data = (uint8_t *) outptr;
- meta.pre_compressed = false;
- meta.image_width = in_meta.image_width;
- meta.image_length = in_meta.image_length;
- meta.x_resolution = in_meta.x_resolution;
- meta.y_resolution = in_meta.y_resolution;
- meta.resolution_unit = in_meta.resolution_unit;
- meta.bits_per_sample = 8;
- meta.samples_per_pixel = in_meta.samples_per_pixel;
- meta.compression = COMPRESSION_JPEG;
- meta.photometric = PHOTOMETRIC_RGB;
- }
- else
- {
- #if 1
- start = rdtscll();
- switch (in_meta.photometric)
- {
- case PHOTOMETRIC_CIELAB:
- printf("CIELAB\n");
- /* Convert this to sRGB first */
- /* The default luminant is D50 */
- set_lab_illuminant(&lab_param, 96.422f, 100.000f, 82.521f);
- set_lab_gamut(&lab_param, 0, 100, -128, 127, -128, 127, true);
- lab_to_srgb(&lab_param, data, data, in_meta.image_width*in_meta.image_length);
- break;
- case PHOTOMETRIC_RGB:
- printf("RGB\n");
- if (in_meta.bits_per_sample == 8)
- {
- }
- else if (in_meta.bits_per_sample == 16)
- {
- printf("Pack %d to %d\n", totdata, in_meta.samples_per_pixel*in_meta.image_width*in_meta.image_length);
- if ((outptr = malloc(in_meta.samples_per_pixel*in_meta.image_width*in_meta.image_length)) == NULL)
- printf("Failed to allocate buffer\n");
- for (i = 0; i < in_meta.image_width*in_meta.image_length; i++)
- {
- outptr[in_meta.samples_per_pixel*i + 0] = (data[in_meta.samples_per_pixel*2*i + 1] << 4) | (data[in_meta.samples_per_pixel*2*i + 0] >> 4);
- outptr[in_meta.samples_per_pixel*i + 1] = (data[in_meta.samples_per_pixel*2*i + 3] << 4) | (data[in_meta.samples_per_pixel*2*i + 2] >> 4);
- outptr[in_meta.samples_per_pixel*i + 2] = (data[in_meta.samples_per_pixel*2*i + 5] << 4) | (data[in_meta.samples_per_pixel*2*i + 4] >> 4);
- }
- free(data);
- data = (uint8_t *) outptr;
- off = in_meta.samples_per_pixel*in_meta.image_width*in_meta.image_length;
- in_meta.bits_per_sample = 8;
- }
- else
- {
- uint32_t bitstream;
- int bits;
- int j;
- /* Deal with the messy cases where the number of bits is not a whole number of bytes. */
- printf("Pack %d to %d\n", totdata, in_meta.samples_per_pixel*in_meta.image_width*in_meta.image_length);
- if ((outptr = malloc(in_meta.samples_per_pixel*in_meta.image_width*in_meta.image_length)) == NULL)
- printf("Failed to allocate buffer\n");
- bitstream = 0;
- bits = 0;
- j = 0;
- for (i = 0; i < in_meta.image_width*in_meta.image_length; i++)
- {
- for (k = 0; k < in_meta.samples_per_pixel; k++)
- {
- while (bits < in_meta.bits_per_sample)
- {
- bitstream = (bitstream << 8) | data[j++];
- bits += 8;
- }
- outptr[in_meta.samples_per_pixel*i + k] = bitstream >> (bits - 8);
- bits -= in_meta.bits_per_sample;
- }
- }
- free(data);
- data = (uint8_t *) outptr;
- off = in_meta.samples_per_pixel*in_meta.image_width*in_meta.image_length;
- in_meta.bits_per_sample = 8;
- }
- break;
- }
- #if 0
- /* The default luminant is D50 */
- set_lab_illuminant(&lab_param, 96.422f, 100.000f, 82.521f);
- set_lab_gamut(&lab_param, 0, 100, -85, 85, -75, 125, false);
- if (!t42_srgb_to_itulab_jpeg(&logging2, &lab_param, (tdata_t) &outptr, &outsize, data, off, in_meta.image_width, in_meta.image_length, 3))
- {
- printf("Failed to convert to ITULAB (B).\n");
- return 1;
- }
- end = rdtscll();
- printf("Duration %" PRIu64 "\n", end - start);
- free(data);
- data = (uint8_t *) outptr;
- off = outsize;
- #endif
- #endif
- meta.pre_compressed = false;
- meta.image_width = in_meta.image_width;
- meta.image_length = in_meta.image_length;
- meta.x_resolution = in_meta.x_resolution;
- meta.y_resolution = in_meta.y_resolution;
- meta.resolution_unit = in_meta.resolution_unit;
- meta.bits_per_sample = 8;
- meta.samples_per_pixel = in_meta.samples_per_pixel;
- meta.compression = COMPRESSION_JPEG;
- meta.photometric = PHOTOMETRIC_RGB;
- }
- write_file(&meta, page_no, data);
- break;
- case 4:
- printf("Photometric is %d\n", in_meta.photometric);
- /* We now have the image in memory in RGB form */
- if (in_meta.photometric == PHOTOMETRIC_ITULAB)
- {
- /* We are already in the ITULAB color space */
- #if 0
- if (!t42_itulab_to_itulab(&logging2, (tdata_t) &outptr, &outsize, data, off, in_meta.image_width, in_meta.image_length, 3))
- {
- printf("Failed to convert to ITULAB (C).\n");
- return 1;
- }
- #else
- outsize = 0;
- #endif
- free(data);
- data = (uint8_t *) outptr;
- off = outsize;
- }
- else
- {
- start = rdtscll();
- switch (in_meta.photometric)
- {
- case PHOTOMETRIC_CIELAB:
- printf("CIELAB\n");
- /* TODO: This doesn't work yet */
- /* Convert this to sRGB first */
- /* The default luminant is D50 */
- set_lab_illuminant(&lab_param, 96.422f, 100.000f, 82.521f);
- set_lab_gamut(&lab_param, 0, 100, -128, 127, -128, 127, true);
- lab_to_srgb(&lab_param, data, data, in_meta.image_width*in_meta.image_length);
- break;
- case PHOTOMETRIC_SEPARATED:
- for (y = 0; y < in_meta.image_length; y++)
- {
- for (x = 0; x < in_meta.image_width; x++)
- {
- k = data[(y*in_meta.image_width + x)*4 + 0] + data[(y*in_meta.image_width + x)*4 + 3];
- if (k > 255)
- k = 255;
- data[(y*in_meta.image_width + x)*3 + 0] = 255 - k;
- k = data[(y*in_meta.image_width + x)*4 + 1] + data[(y*in_meta.image_width + x)*4 + 3];
- if (k > 255)
- k = 255;
- data[(y*in_meta.image_width + x)*3 + 1] = 255 - k;
- k = data[(y*in_meta.image_width + x)*4 + 2] + data[(y*in_meta.image_width + x)*4 + 3];
- if (k > 255)
- k = 255;
- data[(y*in_meta.image_width + x)*3 + 2] = 255 - k;
- }
- }
- off = 3*in_meta.image_width*in_meta.image_length;
- in_meta.bits_per_sample = 8;
- break;
- }
- /* The default luminant is D50 */
- set_lab_illuminant(&lab_param, 96.422f, 100.000f, 82.521f);
- set_lab_gamut(&lab_param, 0, 100, -85, 85, -75, 125, false);
- //if (!t42_srgb_to_itulab_jpeg(&logging2, &lab_param, (tdata_t) &outptr, &outsize, data, off, in_meta.image_width, in_meta.image_length, 3))
- {
- printf("Failed to convert to ITULAB (D).\n");
- return 1;
- }
- end = rdtscll();
- printf("Duration %" PRIu64 "\n", end - start);
- off = outsize;
- in_meta.bits_per_sample = 8;
- }
- meta.pre_compressed = false;
- meta.image_width = in_meta.image_width;
- meta.image_length = in_meta.image_length;
- meta.x_resolution = in_meta.x_resolution;
- meta.y_resolution = in_meta.y_resolution;
- meta.resolution_unit = in_meta.resolution_unit;
- meta.bits_per_sample = 8;
- meta.samples_per_pixel = 3;
- meta.compression = COMPRESSION_JPEG;
- meta.photometric = PHOTOMETRIC_RGB;
- write_file(&meta, page_no, data);
- break;
- }
- }
- printf("XXX - image is %d by %d, %d bytes\n", in_meta.image_width, in_meta.image_length, (int) off);
- /* We now have the image in memory in ITULAB form */
- meta.pre_compressed = false;
- meta.compressed_image_len = off;
- meta.image_width = in_meta.image_width;
- meta.image_length = in_meta.image_length;
- meta.x_resolution = in_meta.x_resolution;
- meta.y_resolution = in_meta.y_resolution;
- meta.resolution_unit = in_meta.resolution_unit;
- meta.bits_per_sample = 8;
- meta.samples_per_pixel = 3;
- meta.compression = COMPRESSION_JPEG;
- #if 1
- meta.photometric = PHOTOMETRIC_RGB;
- #elif 1
- /* Most image processors won't know what to do with the ITULAB colorspace.
- So we'll be converting it to RGB for portability. */
- /* If PHOTOMETRIC_ITULAB is not available the admin cannot enable color fax anyway.
- This is done so that older libtiffs without it can build fine. */
- meta.photometric = PHOTOMETRIC_ITULAB;
- #else
- meta.photometric = PHOTOMETRIC_YCBCR;
- #endif
- meta.YCbCrSubsampleHoriz = in_meta.YCbCrSubsampleHoriz;
- meta.YCbCrSubsampleVert = in_meta.YCbCrSubsampleVert;
- if ((tif = TIFFOpen(destination_file, "w")) == NULL)
- {
- printf("Unable to open '%s'!\n", destination_file);
- return 1;
- }
- TIFFSetField(tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
- TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, meta.image_width);
- /* libtiff requires IMAGELENGTH to be set before SAMPLESPERPIXEL,
- or StripOffsets and StripByteCounts will have SAMPLESPERPIXEL values */
- TIFFSetField(tif, TIFFTAG_IMAGELENGTH, meta.image_length);
- TIFFSetField(tif, TIFFTAG_COMPRESSION, meta.compression);
- TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, meta.bits_per_sample);
- TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, meta.samples_per_pixel);
- TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
- TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
- TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, meta.image_length);
- TIFFSetField(tif, TIFFTAG_XRESOLUTION, meta.x_resolution);
- TIFFSetField(tif, TIFFTAG_YRESOLUTION, meta.y_resolution);
- TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, meta.resolution_unit);
- TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, meta.photometric);
- if (meta.samples_per_pixel > 1 && (meta.YCbCrSubsampleHoriz || meta.YCbCrSubsampleVert))
- TIFFSetField(tif, TIFFTAG_YCBCRSUBSAMPLING, meta.YCbCrSubsampleHoriz, meta.YCbCrSubsampleVert);
- TIFFSetField(tif, TIFFTAG_SOFTWARE, "spandsp");
- TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "Test");
- TIFFSetField(tif, TIFFTAG_DATETIME, "2011/02/03 12:30:45");
- TIFFSetField(tif, TIFFTAG_MAKE, "soft-switch.org");
- TIFFSetField(tif, TIFFTAG_MODEL, "spandsp");
- TIFFSetField(tif, TIFFTAG_HOSTCOMPUTER, "i7.coppice.org");
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- /* Make space for this to be filled in later */
- TIFFSetField(tif, TIFFTAG_GLOBALPARAMETERSIFD, 0);
- #endif
- if (meta.pre_compressed)
- {
- if (TIFFWriteRawStrip(tif, 0, (tdata_t) data, meta.compressed_image_len) == -1)
- {
- printf("Write error to TIFF file\n");
- return 1;
- }
- free(data);
- }
- else
- {
- if (in_meta.samples_per_pixel > 1)
- {
- bytes_per_row = ((meta.bits_per_sample + 7)/8)*meta.image_width*meta.samples_per_pixel;
- totdata = meta.image_length*bytes_per_row;
- /* The default luminant is D50 */
- set_lab_illuminant(&lab_param, 96.422f, 100.000f, 82.521f);
- set_lab_gamut(&lab_param, 0, 100, -85, 85, -75, 125, false);
- #if 0
- start = rdtscll();
- data2 = NULL;
- totdata = 0;
- if (!t42_itulab_to_JPEG(&logging2, &lab_param, (void **) &data2, &totdata, data, off))
- {
- printf("Failed to convert from ITULAB (A).\n");
- return 1;
- }
- end = rdtscll();
- printf("Duration %" PRIu64 "\n", end - start);
- printf("Compressed length %d (%p)\n", totdata, data2);
- if (TIFFWriteRawStrip(tif, 0, data2, totdata) < 0)
- {
- printf("Failed to convert from ITULAB (B).\n");
- return 1;
- }
- free(data);
- data = data2;
- #elif 1
- if ((data2 = malloc(totdata)) == NULL)
- {
- printf("Failed to allocate buffer\n");
- exit(2);
- }
- start = rdtscll();
- //if (!t42_itulab_jpeg_to_srgb(&logging2, &lab_param, data2, &off, data, off, &meta.image_width, &meta.image_length, &meta.samples_per_pixel))
- {
- printf("Failed to convert from ITULAB.\n");
- return 1;
- }
- end = rdtscll();
- printf("Duration %" PRIu64 "\n", end - start);
- free(data);
- data = data2;
- #endif
- }
- off = 0;
- bytes_per_row = ((meta.bits_per_sample + 7)/8)*meta.image_width*meta.samples_per_pixel;
- for (row = 0; row < meta.image_length; row++)
- {
- if (TIFFWriteScanline(tif, &data[off], row, 0) < 0)
- return 1;
- off += bytes_per_row;
- }
- free(data);
- }
- if (!TIFFWriteDirectory(tif))
- printf("Failed to write directory.\n");
- #if defined(SPANDSP_SUPPORT_TIFF_FX) && defined(HAVE_TIF_DIR_H)
- if (!TIFFCreateCustomDirectory(tif, &tiff_fx_field_array))
- {
- TIFFSetField(tif, TIFFTAG_PROFILETYPE, PROFILETYPE_G3_FAX);
- TIFFSetField(tif, TIFFTAG_FAXPROFILE, FAXPROFILE_F);
- TIFFSetField(tif, TIFFTAG_CODINGMETHODS, CODINGMETHODS_T4_1D | CODINGMETHODS_T4_2D | CODINGMETHODS_T6);
- TIFFSetField(tif, TIFFTAG_VERSIONYEAR, "1998");
- TIFFSetField(tif, TIFFTAG_MODENUMBER, 3);
- diroff = 0;
- if (!TIFFWriteCustomDirectory(tif, &diroff))
- printf("Failed to write custom directory.\n");
- if (!TIFFSetDirectory(tif, (tdir_t) page_no))
- printf("Failed to set directory.\n");
- if (!TIFFSetField(tif, TIFFTAG_GLOBALPARAMETERSIFD, diroff))
- printf("Failed to set global parameters IFD.\n");
- if (!TIFFWriteDirectory(tif))
- printf("Failed to write directory.\n");
- }
- #endif
- TIFFClose(tif);
- printf("Done!\n");
- return 0;
- }
- /*- End of function --------------------------------------------------------*/
- /*- End of file ------------------------------------------------------------*/
|