"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "f.pixmap.cc" between
fotoxx-23.0.tar.gz and fotoxx-23.1.tar.gz

About: fotoxx is a program for photo editing and collection management.

f.pixmap.cc  (fotoxx-23.0):f.pixmap.cc  (fotoxx-23.1)
/******************************************************************************* * /******************************************************************************* *
Fotoxx edit photos and manage collections Fotoxx - edit photos and manage collections
Copyright 2007-2023 Michael Cornelison Copyright 2007-2023 Michael Cornelison
source code URL: https://kornelix.net source code URL: https://kornelix.net
contact: mkornelix@gmail.com contact: mkornelix@gmail.com
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. See https://www.gnu.org/licenses (at your option) any later version. See https://www.gnu.org/licenses
skipping to change at line 548 skipping to change at line 548
NOT THREAD SAFE NOT THREAD SAFE
******************************************************************************** */ ******************************************************************************** */
namespace pxmrescale { namespace pxmrescale {
float *ppix1, *ppix2; float *ppix1, *ppix2;
int ww1, hh1, ww2, hh2, nc; int ww1, hh1, ww2, hh2, nc;
int *px1L, *py1L; int *px1L, *py1L;
float *pxmap, *pymap; float *pxmap, *pymap;
int maxmapx, maxmapy; int maxmapx, maxmapy;
int nwt;
} }
PXM * PXM_rescale(PXM *pxm1, int ww, int hh) PXM * PXM_rescale(PXM *pxm1, int ww, int hh)
{ {
using namespace pxmrescale; using namespace pxmrescale;
void * pxm_rescale_thread(void *arg); void * pxm_rescale_thread(void *arg);
PXM *pxm2; PXM *pxm2;
int px1, py1, px2, py2; int px1, py1, px2, py2;
skipping to change at line 645 skipping to change at line 644
else fx = 1; else fx = 1;
ii = px2 * maxmapx + pxm; ii = px2 * maxmapx + pxm;
pxmap[ii] = 0.999 * fx / scalex; pxmap[ii] = 0.999 * fx / scalex;
} }
ii = px2 * maxmapx + pxm; ii = px2 * maxmapx + pxm;
pxmap[ii] = -1; pxmap[ii] = -1;
} }
nwt = NWT; do_wthreads(pxm_rescale_thread,NWT);
// threads
if (nwt > 4) nwt = 4;
// slower > 4
do_wthreads(pxm_rescale_thread,nwt);
zfree(px1L); zfree(px1L);
zfree(py1L); zfree(py1L);
zfree(pxmap); zfree(pxmap);
zfree(pymap); zfree(pymap);
return pxm2; return pxm2;
} }
void * pxm_rescale_thread(void *arg) // worker thread function void * pxm_rescale_thread(void *arg) // worker thread function
skipping to change at line 669 skipping to change at line 666
using namespace pxmrescale; using namespace pxmrescale;
int index = *((int *) arg); int index = *((int *) arg);
int px1, py1, px2, py2; int px1, py1, px2, py2;
int pxl, pyl, pxm, pym, ii; int pxl, pyl, pxm, pym, ii;
float *pixel1, *pixel2; float *pixel1, *pixel2;
float fx, fy, ftot; float fx, fy, ftot;
float chan[6]; float chan[6];
int pcc = nc * sizeof(float); int pcc = nc * sizeof(float);
for (py2 = index; py2 < hh2; py2 += nwt) // loop output y-pixels for (py2 = index; py2 < hh2; py2 += NWT) // loop output y-pixels
{ {
pyl = py1L[py2]; // corresp. 1st input y-pixel pyl = py1L[py2]; // corresp. 1st input y-pixel
for (px2 = 0; px2 < ww2; px2++) // loop output x-pixels for (px2 = 0; px2 < ww2; px2++) // loop output x-pixels
{ {
pxl = px1L[px2]; // corresp. 1st input x-pixel pxl = px1L[px2]; // corresp. 1st input x-pixel
memset(chan,0,pcc); // initz. output pixel memset(chan,0,pcc); // initz. output pixel
for (py1 = pyl, pym = 0; ; py1++, pym++) // loop overlapping input y-pixels for (py1 = pyl, pym = 0; ; py1++, pym++) // loop overlapping input y-pixels
skipping to change at line 1208 skipping to change at line 1205
} }
for (int ii = 0; ii < NWT; ii++) for (int ii = 0; ii < NWT; ii++)
wait_Jthread(tid[ii]); wait_Jthread(tid[ii]);
return pxb2; return pxb2;
} }
void * pxb_half_thread(void *arg) void * pxb_half_thread(void *arg)
{ {
int row, col, ch, nc, rgb; int row, col, ch1, nc, rgb;
uint8 *pix1a, *pix1b, *pix2; uint8 *pix1a, *pix1b, *pix2;
void ** args = (void **) arg; void ** args = (void **) arg;
pxb_half_data_t *P = (pxb_half_data_t *) args[0]; pxb_half_data_t *P = (pxb_half_data_t *) args[0];
int index = * ((int *) args[1]); int index = * ((int *) args[1]);
nc = P->nc1; nc = P->nc1;
for (row = index; row < P->hh2; row += NWT) // loop output rows for (row = index; row < P->hh2; row += NWT) // loop output rows
{ {
pix1a = P->pixels1 + (uint)(P->rs1) * row * 2; // 2 input rows pix1a = P->pixels1 + (uint)(P->rs1) * row * 2; // 2 input rows
pix1b = pix1a + P->rs1; pix1b = pix1a + P->rs1;
pix2 = P->pixels2 + (uint)(P->rs2) * row; // output row pix2 = P->pixels2 + (uint)(P->rs2) * row; // output row
for (col = 0; col < P->ww2 * nc; col += nc) // output col for (col = 0; col < P->ww2 * nc; col += nc) // output col
{ {
for (ch = 0; ch < nc; ch++) // loop channels for (ch1 = 0; ch1 < nc; ch1++) // loop channels
{ {
rgb = pix1a[ch] + pix1a[ch+nc] + pix1b[ch] + pix1b[ch+nc]; rgb = pix1a[ch1] + pix1a[ch1+nc] + pix1b[ch1] + pix1b[ch1+nc];
// 4 input RGB[A] values // 4 input RGB[A] values
pix2[ch] = rgb / 4; pix2[ch1] = rgb / 4;
// --> 1 output RGB[A] // --> 1 output RGB[A]
} }
pix1a += 2 * nc; pix1a += 2 * nc;
pix1b += 2 * nc; pix1b += 2 * nc;
pix2 += nc; pix2 += nc;
} }
} }
return 0; return 0;
} }
skipping to change at line 1446 skipping to change at line 1443
/******************************************************************************* */ /******************************************************************************* */
// fast PXB pixmap rescale using 'half binomial' interpolation // fast PXB pixmap rescale using 'half binomial' interpolation
// works best when the rescale ratio is between 0.5 and 2.0 // works best when the rescale ratio is between 0.5 and 2.0
typedef struct { typedef struct {
int ww1, hh1, ww2, hh2, rs1, rs2, nc1, nc2; int ww1, hh1, ww2, hh2, rs1, rs2, nc1, nc2;
uint8 *pixels1, *pixels2; uint8 *pixels1, *pixels2;
float xscale, yscale; float xscale, yscale;
int nwt;
} }
pxb_rescale_fast_data_t; pxb_rescale_fast_data_t;
PXB * PXB_rescale_fast(PXB *pxb1, int ww, int hh) PXB * PXB_rescale_fast(PXB *pxb1, int ww, int hh)
{ {
void * pxb_rescale_fast_thread(void *arg); void * pxb_rescale_fast_thread(void *arg);
pxb_rescale_fast_data_t P; pxb_rescale_fast_data_t P;
PXB *pxb2; PXB *pxb2;
P.ww1 = pxb1->ww; // input image data P.ww1 = pxb1->ww; // input image data
skipping to change at line 1475 skipping to change at line 1471
P.hh2 = hh; P.hh2 = hh;
P.nc2 = P.nc1; P.nc2 = P.nc1;
pxb2 = PXB_make(P.ww2,P.hh2,P.nc2); pxb2 = PXB_make(P.ww2,P.hh2,P.nc2);
if (! pxb2) quitxx(); if (! pxb2) quitxx();
P.rs2 = pxb2->rs; P.rs2 = pxb2->rs;
P.pixels2 = pxb2->pixels; P.pixels2 = pxb2->pixels;
P.xscale = 1.0 * (P.ww1-1) / P.ww2; P.xscale = 1.0 * (P.ww1-1) / P.ww2;
P.yscale = 1.0 * (P.hh1-1) / P.hh2; P.yscale = 1.0 * (P.hh1-1) / P.hh2;
P.nwt = NWT;
// limit to 4 threads
if (P.nwt > 4) P.nwt = 4;
// (more not helpful)
void *args[NWT][2]; void *args[NWT][2];
pthread_t tid[NWT]; pthread_t tid[NWT];
for (int ii = 0; ii < P.nwt; ii++) { // start working threads for (int ii = 0; ii < NWT; ii++) { // start working threads
args[ii][0] = &P; args[ii][0] = &P;
args[ii][1] = &Nval[ii]; args[ii][1] = &Nval[ii];
tid[ii] = start_Jthread(pxb_rescale_fast_thread,args[ii]); tid[ii] = start_Jthread(pxb_rescale_fast_thread,args[ii]);
} }
for (int ii = 0; ii < P.nwt; ii++) // wait for all done for (int ii = 0; ii < NWT; ii++) // wait for all done
wait_Jthread(tid[ii]); wait_Jthread(tid[ii]);
return pxb2; return pxb2;
} }
void * pxb_rescale_fast_thread(void *arg) void * pxb_rescale_fast_thread(void *arg)
{ {
int px1, py1, px2, py2; int px1, py1, px2, py2;
uint8 *pix10, *pix11, *pix2; uint8 *pix10, *pix11, *pix2;
void ** args = (void **) arg; void ** args = (void **) arg;
int index = * ((int *) args[1]); int index = * ((int *) args[1]);
set_cpu_affinity(index); // stay on same cpu if possible set_cpu_affinity(index); // stay on same cpu if possible
pxb_rescale_fast_data_t *P = (pxb_rescale_fast_data_t *) args[0]; pxb_rescale_fast_data_t *P = (pxb_rescale_fast_data_t *) args[0];
for (py2 = index; py2 < P->hh2; py2 += P->nwt) // loop output pixels for (py2 = index; py2 < P->hh2; py2 += NWT) // loop output pixels
for (px2 = 0; px2 < P->ww2; px2++) for (px2 = 0; px2 < P->ww2; px2++)
{ {
px1 = px2 * P->xscale; // input pixel corresponding px1 = px2 * P->xscale; // input pixel corresponding
py1 = py2 * P->yscale; // to output pixel py1 = py2 * P->yscale; // to output pixel
pix10 = P->pixels1 + py1 * P->rs1 + px1 * P->nc1; // input pixel RGB data pix10 = P->pixels1 + py1 * P->rs1 + px1 * P->nc1; // input pixel RGB data
pix11 = pix10 + P->nc1; // next pixel right pix11 = pix10 + P->nc1; // next pixel right
pix2 = P->pixels2 + py2 * P->rs2 + px2 * P->nc2; // output pixel pix2 = P->pixels2 + py2 * P->rs2 + px2 * P->nc2; // output pixel
skipping to change at line 1615 skipping to change at line 1608
PXB * PXB_rotate(PXB *pxb1, float angle) PXB * PXB_rotate(PXB *pxb1, float angle)
{ {
PXB *pxb2; PXB *pxb2;
int nc, ac; int nc, ac;
int ww1, hh1, rs1, ww2, hh2, rs2; int ww1, hh1, rs1, ww2, hh2, rs2;
int px2, py2, px0, py0; int px2, py2, px0, py0;
float px1, py1; float px1, py1;
float f0, f1, f2, f3, red, green, blue, alpha = 0; float f0, f1, f2, f3, red, green, blue, alpha = 0;
float a, b, d, e, ww15, hh15, ww25, hh25; float a, b, d, e, ww15, hh15, ww25, hh25;
uchar *ppix1, *ppix2, *pix0, *pix1, *pix2, *pix3; uch *ppix1, *ppix2, *pix0, *pix1, *pix2, *pix3;
ww1 = pxb1->ww; ww1 = pxb1->ww;
hh1 = pxb1->hh; hh1 = pxb1->hh;
nc = pxb1->nc; nc = pxb1->nc;
ac = 0; ac = 0;
if (nc == 4) ac = 1; // has alpha channel if (nc == 4) ac = 1; // has alpha channel
rs1 = ww1 * nc; rs1 = ww1 * nc;
while (angle < -180) angle += 360; // normalize, -180 to +180 while (angle < -180) angle += 360; // normalize, -180 to +180
while (angle > 180) angle -= 360; while (angle > 180) angle -= 360;
skipping to change at line 2080 skipping to change at line 2073
******************************************************************************** */ ******************************************************************************** */
// Load an image file into a PXB pixmap (8 bit color). // Load an image file into a PXB pixmap (8 bit color).
// Also sets the following file scope variables: // Also sets the following file scope variables:
// f_load_type = "jpg" "tif" "png" "RAW" "video" "other" // f_load_type = "jpg" "tif" "png" "RAW" "video" "other"
// f_load_bpc = disk file bits per color = 8/16 // f_load_bpc = disk file bits per color = 8/16
// f_load_size = disk file size // f_load_size = disk file size
// If Fack is true, failure will cause a popup ACK dialog // If Fack is true, failure will cause a popup ACK dialog
// Do not call from a thread with Fack true. // Do not call from a thread with Fack true.
PXB * PXB_load(cchar *file, int Fack) PXB * PXB_load(ch *file, int Fack)
{ {
int err; int err;
FTYPE ftype; FTYPE ftype;
char *file2 = 0; ch *file2 = 0;
char framefile[200]; ch framefile[200];
cchar *pext = 0; ch *pext = 0;
PXB *pxb = 0; PXB *pxb = 0;
STATB statB; STATB statB;
pthread_t tid; pthread_t tid;
cchar *key = "bitspersample"; ch *key = "bitspersample";
char *kdata[1]; ch *kdata[1];
static int Vftf = 1; static int Vftf = 1;
cchar *ffmpegmess = "video files not supported (install ffmpeg)"; ch *ffmpegmess = "video files not supported (install ffmpeg)";
if (! regfile(file,&statB)) { if (! regfile(file,&statB)) {
Plog(0,"%s %s \n","file not found",file); Plog(0,"%s %s \n","file not found",file);
goto errret; goto errret;
} }
f_load_size = statB.st_size; f_load_size = statB.st_size;
f_load_bpc = 8; // default f_load_bpc = 8; // default
ftype = image_file_type(file); ftype = image_file_type(file);
skipping to change at line 2191 skipping to change at line 2184
if (ftype == RAW) if (ftype == RAW)
{ {
if (strcasestr(pext,".mpo")) { if (strcasestr(pext,".mpo")) {
pxb = MPO_PXB_load(file); pxb = MPO_PXB_load(file);
strcpy(f_load_type,"mpo"); strcpy(f_load_type,"mpo");
} }
else { else {
pxb = RAW_PXB_load(file,Fautobright,Fmatchthumb); pxb = RAW_PXB_load(file,Fautobright,Fmatchthumb);
strcpy(f_load_type,"RAW"); strcpy(f_load_type,"RAW");
} }
err = exif_get(file,&key,kdata,1); err = meta_get1(file,(ch **) &key,kdata,1);
if (! err && *kdata) { if (! err && *kdata) {
f_load_bpc_raw = atoi(*kdata); f_load_bpc_raw = atoi(*kdata);
zfree(*kdata); zfree(*kdata);
} }
} }
if (pxb) return pxb; if (pxb) return pxb;
errret: errret:
strcpy(f_load_type,"none"); strcpy(f_load_type,"none");
skipping to change at line 2217 skipping to change at line 2210
/******************************************************************************* */ /******************************************************************************* */
// Load an image file into a PXM pixmap (float color). // Load an image file into a PXM pixmap (float color).
// Also sets the following file scope variables: // Also sets the following file scope variables:
// f_load_type = "jpg" "tif" "png" "RAW" "other" // f_load_type = "jpg" "tif" "png" "RAW" "other"
// f_load_bpc = disk file bits per color = 8/16 // f_load_bpc = disk file bits per color = 8/16
// f_load_size = disk file size // f_load_size = disk file size
// If Fack is true, failure will cause a popup ACK dialog // If Fack is true, failure will cause a popup ACK dialog
// Do not call from a thread with Fack true. // Do not call from a thread with Fack true.
PXM * PXM_load(cchar *file, int Fack) PXM * PXM_load(ch *file, int Fack)
{ {
int err; int err;
FTYPE ftype; FTYPE ftype;
cchar *pext; ch *pext;
PXM *pxm = 0; PXM *pxm = 0;
STATB statB; STATB statB;
cchar *key = "bitspersample"; ch *key = "bitspersample";
char *kdata[1]; ch *kdata[1];
zadd_locked(Ffuncbusy,+1); zadd_locked(Ffuncbusy,+1);
update_Fpanel(); update_Fpanel();
zmainloop(); zmainloop();
if (! regfile(file,&statB)) { if (! regfile(file,&statB)) {
Plog(0,"%s %s \n","file not found",file); Plog(0,"%s %s \n","file not found",file);
goto errret; goto errret;
} }
skipping to change at line 2298 skipping to change at line 2291
if (ftype == RAW) if (ftype == RAW)
{ {
if (strcasestr(pext,".mpo")) { if (strcasestr(pext,".mpo")) {
pxm = MPO_PXM_load(file); pxm = MPO_PXM_load(file);
strcpy(f_load_type,"mpo"); strcpy(f_load_type,"mpo");
} }
else { else {
pxm = RAW_PXM_load(file,Fautobright,Fmatchthumb); pxm = RAW_PXM_load(file,Fautobright,Fmatchthumb);
strcpy(f_load_type,"RAW"); strcpy(f_load_type,"RAW");
} }
err = exif_get(file,&key,kdata,1); err = meta_get1(file,(ch **) &key,kdata,1);
if (! err && *kdata) { if (! err && *kdata) {
f_load_bpc_raw = atoi(*kdata); f_load_bpc_raw = atoi(*kdata);
zfree(*kdata); zfree(*kdata);
} }
} }
if (pxm) { if (pxm) {
zadd_locked(Ffuncbusy,-1); zadd_locked(Ffuncbusy,-1);
return pxm; return pxm;
} }
skipping to change at line 2326 skipping to change at line 2319
} }
/******************************************************************************* */ /******************************************************************************* */
// Save a PXB pixmap to a specified file, bits/color, and quality level. // Save a PXB pixmap to a specified file, bits/color, and quality level.
// If output file is JPEG, bpc is 8 and quality is used for compression level. // If output file is JPEG, bpc is 8 and quality is used for compression level.
// If output file is TIFF or PNG, bpc may be 8 or 16 and quality is ignored. // If output file is TIFF or PNG, bpc may be 8 or 16 and quality is ignored.
// If Fack is true, failure will cause a popup ACK dialog. // If Fack is true, failure will cause a popup ACK dialog.
// Return 0 if OK, +N if error // Return 0 if OK, +N if error
int PXB_save(PXB *pxb, cchar *file, int bpc, int quality, int Fack) int PXB_save(PXB *pxb, ch *file, int bpc, int quality, int Fack)
{ {
int err; int err;
cchar *pext; ch *pext;
zadd_locked(Ffuncbusy,+1); zadd_locked(Ffuncbusy,+1);
update_Fpanel(); update_Fpanel();
pext = strrchr(file,'/'); pext = strrchr(file,'/');
if (! pext) pext = file; if (! pext) pext = file;
pext = strrchr(pext,'.'); pext = strrchr(pext,'.');
if (! pext) pext = ""; if (! pext) pext = "";
if (strcasestr(".tif .tiff",pext)) if (strcasestr(".tif .tiff",pext))
skipping to change at line 2377 skipping to change at line 2370
} }
/******************************************************************************* */ /******************************************************************************* */
// Save a PXM pixmap to a specified file, bits/color, and quality level. // Save a PXM pixmap to a specified file, bits/color, and quality level.
// If output file is JPEG, bpc is 8 and quality is used for compression level. // If output file is JPEG, bpc is 8 and quality is used for compression level.
// If output file is TIFF or PNG, bpc may be 8 or 16 and quality is ignored. // If output file is TIFF or PNG, bpc may be 8 or 16 and quality is ignored.
// If Fack is true, failure will cause a popup ACK dialog. // If Fack is true, failure will cause a popup ACK dialog.
// Return 0 if OK, +N if error // Return 0 if OK, +N if error
int PXM_save(PXM *pxm, cchar *file, int bpc, int quality, int Fack) int PXM_save(PXM *pxm, ch *file, int bpc, int quality, int Fack)
{ {
int err; int err;
cchar *pext; ch *pext;
zadd_locked(Ffuncbusy,+1); zadd_locked(Ffuncbusy,+1);
update_Fpanel(); update_Fpanel();
pext = strrchr(file,'/'); pext = strrchr(file,'/');
if (! pext) pext = file; if (! pext) pext = file;
pext = strrchr(pext,'.'); pext = strrchr(pext,'.');
if (! pext) pext = ""; if (! pext) pext = "";
if (strcasestr(".tif .tiff",pext)) if (strcasestr(".tif .tiff",pext))
skipping to change at line 2447 skipping to change at line 2440
{ {
libjpeg_error_ptr errptr = (libjpeg_error_ptr) cinfo->err; libjpeg_error_ptr errptr = (libjpeg_error_ptr) cinfo->err;
// (*cinfo->err->output_message) (cinfo); // suppress secondary message // (*cinfo->err->output_message) (cinfo); // suppress secondary message
longjmp(errptr->setjmp_buffer, 1); longjmp(errptr->setjmp_buffer, 1);
} }
// Load PXB pixmap from JPG file using JPG library. // Load PXB pixmap from JPG file using JPG library.
// set size = 0 to load a full image size // set size = 0 to load a full image size
// set size = N to load an image with width and height <= size // set size = N to load an image with width and height <= size
PXB * JPG_PXB_load(cchar *file, int size) PXB * JPG_PXB_load(ch *file, int size)
{ {
struct jpeg_decompress_struct cinfo; struct jpeg_decompress_struct cinfo;
struct libjpeg_error_mgr jerr; struct libjpeg_error_mgr jerr;
FILE *fid = 0; FILE *fid = 0;
uint8 **row_pointers = 0; uint8 **row_pointers = 0;
uint8 *pixels = 0; uint8 *pixels = 0;
uint8 *buffer; uint8 *buffer;
int ww, hh, num, nc1, nc2, row, nb; int ww, hh, num, nc1, nc2, row, nb;
uint cc; uint cc;
skipping to change at line 2501 skipping to change at line 2494
if (num < 16) { if (num < 16) {
cinfo.scale_num = num; // target size = num/16 * full size cinfo.scale_num = num; // target size = num/16 * full size
cinfo.scale_denom = 16; cinfo.scale_denom = 16;
} }
} }
jpeg_start_decompress(&cinfo); jpeg_start_decompress(&cinfo);
nb = cinfo.rec_outbuf_height; // rows per read nb = cinfo.rec_outbuf_height; // rows per read
nc1 = cinfo.output_components; // color channels nc1 = cinfo.output_components; // color channels
if (nc1 != 3) Plog(0,"JPEG file has %d channels: %s \n",nc1,file); // try anyway 22.18 if (nc1 != 3) Plog(2,"JPEG file has %d channels: %s \n",nc1,file); // try anyway 22.18
ww = cinfo.output_width; // actual output dimensions ww = cinfo.output_width; // actual output dimensions
hh = cinfo.output_height; hh = cinfo.output_height;
cc = imagesize(ww,hh,nc1,1); cc = imagesize(ww,hh,nc1,1);
if (! cc) goto errret; if (! cc) goto errret;
pixels = (uint8 *) zmalloc(cc,"JPG_PXB_load"); // allocate memory for RGB image pixels = (uint8 *) zmalloc(cc,"JPG_PXB_load"); // allocate memory for RGB image
cc = hh * sizeof(void *); // allocate row pointers cc = hh * sizeof(void *); // allocate row pointers
skipping to change at line 2569 skipping to change at line 2562
if (errno) Plog(0,"error: %s \n",strerror(errno)); if (errno) Plog(0,"error: %s \n",strerror(errno));
Plog(0,"jpeg file error: %s \n",file); Plog(0,"jpeg file error: %s \n",file);
if (fid && fileno(fid) != -1) fclose(fid); if (fid && fileno(fid) != -1) fclose(fid);
if (row_pointers) zfree(row_pointers); if (row_pointers) zfree(row_pointers);
if (pixels) zfree(pixels); if (pixels) zfree(pixels);
return 0; return 0;
} }
// Load PXM pixmap from JPG file using JPG library. // Load PXM pixmap from JPG file using JPG library.
PXM * JPG_PXM_load(cchar *file) PXM * JPG_PXM_load(ch *file)
{ {
struct jpeg_decompress_struct cinfo; struct jpeg_decompress_struct cinfo;
struct libjpeg_error_mgr jerr; struct libjpeg_error_mgr jerr;
FILE *fid = 0; FILE *fid = 0;
uint8 **row_pointers = 0; uint8 **row_pointers = 0;
uint8 *pixels = 0; uint8 *pixels = 0;
uint8 *buffer; uint8 *buffer;
int ww, hh, nc1, nc2, row, nb; int ww, hh, nc1, nc2, row, nb;
uint cc; uint cc;
skipping to change at line 2661 skipping to change at line 2654
if (fid && fileno(fid) != -1) fclose(fid); if (fid && fileno(fid) != -1) fclose(fid);
if (row_pointers) zfree(row_pointers); if (row_pointers) zfree(row_pointers);
if (pixels) zfree(pixels); if (pixels) zfree(pixels);
return 0; return 0;
} }
// Write PXB pixmap to JPG file using JPG library. // Write PXB pixmap to JPG file using JPG library.
// quality is compression quality 0-100 // quality is compression quality 0-100
// returns 0 if OK, +N if error. // returns 0 if OK, +N if error.
int PXB_JPG_save(PXB *pxb, cchar *file, int quality) int PXB_JPG_save(PXB *pxb, ch *file, int quality)
{ {
struct jpeg_compress_struct cinfo; struct jpeg_compress_struct cinfo;
struct libjpeg_error_mgr jerr; struct libjpeg_error_mgr jerr;
FILE *fid = 0; FILE *fid = 0;
int ww, hh, nc1, nc2, row, nn; int ww, hh, nc1, nc2, row, nn;
uint cc; uint cc;
uint8 **row_pointers = 0; uint8 **row_pointers = 0;
uint8 *pixels1, *pixels2 = 0; uint8 *pixels1, *pixels2 = 0;
skipping to change at line 2740 skipping to change at line 2733
if (fid && fileno(fid) != -1) fclose(fid); if (fid && fileno(fid) != -1) fclose(fid);
if (row_pointers) zfree(row_pointers); if (row_pointers) zfree(row_pointers);
if (pixels2) zfree(pixels2); if (pixels2) zfree(pixels2);
return 3; return 3;
} }
// Write PXM pixmap to JPG file using JPG library. // Write PXM pixmap to JPG file using JPG library.
// quality is compression quality 0-100 // quality is compression quality 0-100
// returns 0 if OK, +N if error. // returns 0 if OK, +N if error.
int PXM_JPG_save(PXM *pxm, cchar *file, int quality) int PXM_JPG_save(PXM *pxm, ch *file, int quality)
{ {
struct jpeg_compress_struct cinfo; struct jpeg_compress_struct cinfo;
struct libjpeg_error_mgr jerr; struct libjpeg_error_mgr jerr;
FILE *fid = 0; FILE *fid = 0;
int ww, hh, nc1, nc2, row, nn; int ww, hh, nc1, nc2, row, nn;
uint cc; uint cc;
uint8 **row_pointers = 0; uint8 **row_pointers = 0;
uint8 *pixels2 = 0; uint8 *pixels2 = 0;
float *pixels1; float *pixels1;
skipping to change at line 2828 skipping to change at line 2821
/******************************************************************************* */ /******************************************************************************* */
#pragma GCC pop_options // revert to normal optimization #pragma GCC pop_options // revert to normal optimization
/******************************************************************************* * /******************************************************************************* *
TIFF file read and write functions TIFF file read and write functions
******************************************************************************** */ ******************************************************************************** */
// Intercept TIFF warning messages (many) // Intercept TIFF warning messages (many)
void tiffwarninghandler(cchar *module, cchar *format, va_list ap) void tiffwarninghandler(cch *module, cch *format, va_list ap)
{ {
return; // stop flood of crap return; // stop flood of crap
char message[200]; ch message[200];
vsnprintf(message,199,format,ap); vsnprintf(message,199,format,ap);
Plog(0,"TIFF warning: %s %s \n",module,message); Plog(0,"TIFF warning: %s %s \n",module,message);
return; return;
} }
// Load PXB pixmap from TIFF file using TIFF library. // Load PXB pixmap from TIFF file using TIFF library.
// Native TIFF file bits/color >> f_load_bpc // Native TIFF file bits/color >> f_load_bpc
PXB * TIFF_PXB_load(cchar *file) PXB * TIFF_PXB_load(ch *file)
{ {
static int ftf = 1; static int ftf = 1;
TIFF *tiff; TIFF *tiff;
PXB *pxb; PXB *pxb;
char *tiffbuff; ch *tiffbuff;
uint16 bpc, nc1, nc2, pcfg; // pcfg int -> uint16 uint16 bpc, nc1, nc2, pcfg; // pcfg int -> uint16
uint ww, hh, rs1, rps, rwb, stb, nst; uint ww, hh, rs1, rps, rwb, stb, nst;
uint row, strip, cc; uint row, strip, cc;
uint buffsz1, buffsz2, buffsz; uint buffsz1, buffsz2, buffsz;
uint64 buffbytes, buffbits; uint64 buffbytes, buffbits;
if (! regfile(file)) goto errret; // no print error if (! regfile(file)) goto errret; // no print error
if (ftf) { if (ftf) {
TIFFSetWarningHandler(tiffwarninghandler); // intercept TIFF warning messages TIFFSetWarningHandler(tiffwarninghandler); // intercept TIFF warning messages
skipping to change at line 2918 skipping to change at line 2911
rs1 = ww * nc1; // row stride rs1 = ww * nc1; // row stride
if (bpc == 16) rs1 = rs1 * 2; if (bpc == 16) rs1 = rs1 * 2;
buffsz1 = imagesize(stb,nst,1,1); // alternate size calculations buffsz1 = imagesize(stb,nst,1,1); // alternate size calculations
buffsz2 = imagesize(hh,rs1,1,1); buffsz2 = imagesize(hh,rs1,1,1);
buffsz = buffsz1; buffsz = buffsz1;
if (buffsz2 > buffsz) buffsz = buffsz2; // use the larger if (buffsz2 > buffsz) buffsz = buffsz2; // use the larger
if (! buffsz) goto errret; if (! buffsz) goto errret;
buffsz += rwb; // extra row, R.Nolde buffsz += rwb; // extra row, R.Nolde
tiffbuff = (char *) zmalloc(buffsz,"TIFF_PXB_load"); // allocate buffer tiffbuff = (ch *) zmalloc(buffsz,"TIFF_PXB_load"); // allocate buffer
for (strip = 0; strip < nst; strip++) // read strips for (strip = 0; strip < nst; strip++) // read strips
{ {
row = strip * rps; // 1st row in strip row = strip * rps; // 1st row in strip
cc = TIFFReadEncodedStrip(tiff,strip,tiffbuff+row*rs1,stb); cc = TIFFReadEncodedStrip(tiff,strip,tiffbuff+row*rs1,stb);
if (cc > 0) continue; if (cc > 0) continue;
if (cc == 0) break; if (cc == 0) break;
TIFFClose(tiff); // failed TIFFClose(tiff); // failed
zfree(tiffbuff); zfree(tiffbuff);
return ANY_PXB_load(file); // fallback to pixbuf loader return ANY_PXB_load(file); // fallback to pixbuf loader
skipping to change at line 2954 skipping to change at line 2947
return pxb; return pxb;
errret: errret:
return 0; return 0;
} }
// Load PXM pixmap from TIFF file using TIFF library. // Load PXM pixmap from TIFF file using TIFF library.
// Native TIFF file bits/color >> f_load_bpc // Native TIFF file bits/color >> f_load_bpc
PXM * TIFF_PXM_load(cchar *file) PXM * TIFF_PXM_load(ch *file)
{ {
static int ftf = 1; static int ftf = 1;
TIFF *tiff; TIFF *tiff;
PXM *pxm; PXM *pxm;
char *tiffbuff; ch *tiffbuff;
uint16 bpc, nc1, nc2, pcfg; // pcfg int -> uint16 uint16 bpc, nc1, nc2, pcfg; // pcfg int -> uint16
uint ww, hh, rs1, rps, rwb, stb, nst; uint ww, hh, rs1, rps, rwb, stb, nst;
uint row, strip, cc; uint row, strip, cc;
uint buffsz1, buffsz2, buffsz; uint buffsz1, buffsz2, buffsz;
uint64 buffbytes, buffbits; uint64 buffbytes, buffbits;
if (! regfile(file)) goto errret; // no print error if (! regfile(file)) goto errret; // no print error
if (ftf) { if (ftf) {
TIFFSetWarningHandler(tiffwarninghandler); // intercept TIFF warning messages TIFFSetWarningHandler(tiffwarninghandler); // intercept TIFF warning messages
skipping to change at line 3032 skipping to change at line 3025
rs1 = ww * nc1; // row stride rs1 = ww * nc1; // row stride
if (bpc == 16) rs1 = rs1 * 2; if (bpc == 16) rs1 = rs1 * 2;
buffsz1 = imagesize(stb,nst,1,1); // alternate size calculations buffsz1 = imagesize(stb,nst,1,1); // alternate size calculations
buffsz2 = imagesize(hh,rs1,1,1); buffsz2 = imagesize(hh,rs1,1,1);
buffsz = buffsz1; buffsz = buffsz1;
if (buffsz2 > buffsz) buffsz = buffsz2; // use the larger if (buffsz2 > buffsz) buffsz = buffsz2; // use the larger
if (! buffsz) goto errret; if (! buffsz) goto errret;
buffsz += rwb; // extra row, R.Nolde buffsz += rwb; // extra row, R.Nolde
tiffbuff = (char *) zmalloc(buffsz,"TIFF_PXM_load"); // allocate buffer tiffbuff = (ch *) zmalloc(buffsz,"TIFF_PXM_load"); // allocate buffer
for (strip = 0; strip < nst; strip++) // read strips for (strip = 0; strip < nst; strip++) // read strips
{ {
row = strip * rps; // 1st row in strip row = strip * rps; // 1st row in strip
cc = TIFFReadEncodedStrip(tiff,strip,tiffbuff+row*rs1,stb); cc = TIFFReadEncodedStrip(tiff,strip,tiffbuff+row*rs1,stb);
if (cc > 0) continue; if (cc > 0) continue;
if (cc == 0) break; if (cc == 0) break;
TIFFClose(tiff); // failed TIFFClose(tiff); // failed
zfree(tiffbuff); zfree(tiffbuff);
return ANY_PXM_load(file); // fallback to pixbuf loader return ANY_PXM_load(file); // fallback to pixbuf loader
skipping to change at line 3071 skipping to change at line 3064
return pxm; return pxm;
errret: errret:
return 0; return 0;
} }
// Write PXB pixmap to TIFF file using TIFF library. // Write PXB pixmap to TIFF file using TIFF library.
// TIFF file bpc is 8 or 16. // TIFF file bpc is 8 or 16.
// Returns 0 if OK, +N if error. // Returns 0 if OK, +N if error.
int PXB_TIFF_save(PXB *pxb, cchar *file, int bpc) int PXB_TIFF_save(PXB *pxb, ch *file, int bpc)
{ {
static int ftf = 1; static int ftf = 1;
TIFF *tiff; TIFF *tiff;
char *tiffbuff; ch *tiffbuff;
int tiffstat = 0; int tiffstat = 0;
int ww, hh, row; // int not uint int ww, hh, row; // int not uint
int nc1, nc2, rs2, pm = 2, pc = 1, rps = 1; // 22.1 int nc1, nc2, rs2, pm = 2, pc = 1, rps = 1; // 22.1
int comp = tiff_comp_method; int comp = tiff_comp_method;
uint cc; uint cc;
uint16 es[1]; uint16 es[1];
if (ftf) { if (ftf) {
TIFFSetWarningHandler(tiffwarninghandler); // intercept TIFF warning messages TIFFSetWarningHandler(tiffwarninghandler); // intercept TIFF warning messages
ftf = 0; ftf = 0;
skipping to change at line 3106 skipping to change at line 3099
nc1 = pxb->nc; nc1 = pxb->nc;
nc2 = nc1; nc2 = nc1;
rs2 = ww * nc2; // output row stride rs2 = ww * nc2; // output row stride
if (bpc == 16) rs2 = rs2 * 2; if (bpc == 16) rs2 = rs2 * 2;
cc = imagesize(hh,rs2,1,1); cc = imagesize(hh,rs2,1,1);
if (! cc) goto errret; if (! cc) goto errret;
tiffbuff = (char *) zmalloc(cc,"PXB_TIFF_save"); tiffbuff = (ch *) zmalloc(cc,"PXB_TIFF_save");
TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, ww); TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, ww);
TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, bpc); TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, bpc);
TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, nc2); TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, nc2);
TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, pm); TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, pm);
TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, pc); TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, pc);
TIFFSetField(tiff, TIFFTAG_COMPRESSION, comp); TIFFSetField(tiff, TIFFTAG_COMPRESSION, comp);
if (nc2 == 2 || nc2 == 4) { // extra channel is alpha if (nc2 == 2 || nc2 == 4) { // extra channel is alpha
es[0] = EXTRASAMPLE_ASSOCALPHA; es[0] = EXTRASAMPLE_ASSOCALPHA;
skipping to change at line 3146 skipping to change at line 3139
if (tiffstat == 1) return 0; if (tiffstat == 1) return 0;
errret: errret:
return 1; return 1;
} }
// Write PXM pixmap to TIFF file using TIFF library. // Write PXM pixmap to TIFF file using TIFF library.
// TIFF file bpc is 8 or 16. // TIFF file bpc is 8 or 16.
// Returns 0 if OK, +N if error. // Returns 0 if OK, +N if error.
int PXM_TIFF_save(PXM *pxm, cchar *file, int bpc) int PXM_TIFF_save(PXM *pxm, ch *file, int bpc)
{ {
static int ftf = 1; static int ftf = 1;
TIFF *tiff; TIFF *tiff;
char *tiffbuff; ch *tiffbuff;
int tiffstat = 0; int tiffstat = 0;
int ww, hh, row; // int not uint int ww, hh, row; // int not uint
int nc1, nc2, rs2, pm = 2, pc = 1, rps = 1; // 22.1 int nc1, nc2, rs2, pm = 2, pc = 1, rps = 1; // 22.1
int comp = tiff_comp_method; int comp = tiff_comp_method;
uint cc; uint cc;
uint16 es[1]; uint16 es[1];
if (ftf) { if (ftf) {
TIFFSetWarningHandler(tiffwarninghandler); // intercept TIFF warning messages TIFFSetWarningHandler(tiffwarninghandler); // intercept TIFF warning messages
ftf = 0; ftf = 0;
skipping to change at line 3181 skipping to change at line 3174
nc1 = pxm->nc; nc1 = pxm->nc;
nc2 = nc1; nc2 = nc1;
rs2 = ww * nc2; // output row stride rs2 = ww * nc2; // output row stride
if (bpc == 16) rs2 = rs2 * 2; if (bpc == 16) rs2 = rs2 * 2;
cc = imagesize(hh,rs2,1,1); cc = imagesize(hh,rs2,1,1);
if (! cc) goto errret; if (! cc) goto errret;
tiffbuff = (char *) zmalloc(cc,"PXM_TIFF_save"); tiffbuff = (ch *) zmalloc(cc,"PXM_TIFF_save");
TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, ww); TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, ww);
TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, bpc); TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, bpc);
TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, nc2); TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, nc2);
TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, pm); TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, pm);
TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, pc); TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, pc);
TIFFSetField(tiff, TIFFTAG_COMPRESSION, comp); TIFFSetField(tiff, TIFFTAG_COMPRESSION, comp);
if (nc2 == 2 || nc2 == 4) { // extra channel is alpha if (nc2 == 2 || nc2 == 4) { // extra channel is alpha
es[0] = EXTRASAMPLE_ASSOCALPHA; es[0] = EXTRASAMPLE_ASSOCALPHA;
skipping to change at line 3224 skipping to change at line 3217
return 1; return 1;
} }
/******************************************************************************* * /******************************************************************************* *
PNG file read and write functions PNG file read and write functions
******************************************************************************** */ ******************************************************************************** */
// Load PXB pixmap from PNG file using PNG library. // Load PXB pixmap from PNG file using PNG library.
// Native PNG file bits/color >> f_load_bpc // Native PNG file bits/color >> f_load_bpc
PXB * PNG_PXB_load(cchar *file) PXB * PNG_PXB_load(ch *file)
{ {
png_structp pngstruct = 0; png_structp pngstruct = 0;
png_infop pnginfo = 0; png_infop pnginfo = 0;
FILE *fid = 0; FILE *fid = 0;
int ww, hh, bpc, nc1, nc2, rs1, row, colortype; int ww, hh, bpc, nc1, nc2, rs1, row, colortype;
uchar *pngbuff, **pngrows; uch *pngbuff, **pngrows;
PXB *pxb; PXB *pxb;
uint cc; uint cc;
if (! regfile(file)) goto errret; // no print error if (! regfile(file)) goto errret; // no print error
fid = fopen(file,"r"); // open file fid = fopen(file,"r"); // open file
if (! fid) { if (! fid) {
Plog(0,"file error: %s %s \n",file,strerror(errno)); Plog(0,"file error: %s %s \n",file,strerror(errno));
goto errret; goto errret;
} }
skipping to change at line 3290 skipping to change at line 3283
png_destroy_read_struct(&pngstruct,&pnginfo,0); png_destroy_read_struct(&pngstruct,&pnginfo,0);
goto errret; goto errret;
} }
rs1 = ww * nc1; // png input row stride rs1 = ww * nc1; // png input row stride
if (bpc == 16) rs1 = rs1 * 2; if (bpc == 16) rs1 = rs1 * 2;
cc = imagesize(hh,rs1,1,1); cc = imagesize(hh,rs1,1,1);
if (! cc) goto errret; if (! cc) goto errret;
pngbuff = (uchar *) zmalloc(cc,"PNG_PXB_load"); // png file input buffer pngbuff = (uch *) zmalloc(cc,"PNG_PXB_load"); // png file input buffer
for (row = 0; row < hh; row++) // get all png rows for (row = 0; row < hh; row++) // get all png rows
memcpy(pngbuff+row*rs1,pngrows[row],rs1); memcpy(pngbuff+row*rs1,pngrows[row],rs1);
png_destroy_read_struct(&pngstruct,&pnginfo,0); // release memory png_destroy_read_struct(&pngstruct,&pnginfo,0); // release memory
if (bpc == 8) pixelvert((uint8 *) pngbuff,pxb->pixels,ww,hh,nc1,nc2); // convert pixel data if (bpc == 8) pixelvert((uint8 *) pngbuff,pxb->pixels,ww,hh,nc1,nc2); // convert pixel data
if (bpc == 16) pixelvert((uint16 *) pngbuff,pxb->pixels,ww,hh,nc1,nc2); if (bpc == 16) pixelvert((uint16 *) pngbuff,pxb->pixels,ww,hh,nc1,nc2);
zfree(pngbuff); zfree(pngbuff);
skipping to change at line 3313 skipping to change at line 3306
return pxb; return pxb;
errret: errret:
if (fid && fileno(fid) != -1) fclose(fid); if (fid && fileno(fid) != -1) fclose(fid);
return 0; return 0;
} }
// Load PXM pixmap from PNG file using PNG library. // Load PXM pixmap from PNG file using PNG library.
// Native PNG file bits/color >> f_load_bpc // Native PNG file bits/color >> f_load_bpc
PXM * PNG_PXM_load(cchar *file) PXM * PNG_PXM_load(ch *file)
{ {
png_structp pngstruct = 0; png_structp pngstruct = 0;
png_infop pnginfo = 0; png_infop pnginfo = 0;
FILE *fid = 0; FILE *fid = 0;
int ww, hh, bpc, nc1, nc2, rs1, row, colortype; int ww, hh, bpc, nc1, nc2, rs1, row, colortype;
uchar *pngbuff, **pngrows; uch *pngbuff, **pngrows;
PXM *pxm; PXM *pxm;
uint cc; uint cc;
if (! regfile(file)) goto errret; // no print error if (! regfile(file)) goto errret; // no print error
fid = fopen(file,"r"); // open file fid = fopen(file,"r"); // open file
if (! fid) { if (! fid) {
Plog(0,"file error: %s %s \n",file,strerror(errno)); Plog(0,"file error: %s %s \n",file,strerror(errno));
goto errret; goto errret;
} }
skipping to change at line 3379 skipping to change at line 3372
png_destroy_read_struct(&pngstruct,&pnginfo,0); png_destroy_read_struct(&pngstruct,&pnginfo,0);
goto errret; goto errret;
} }
rs1 = ww * nc1; // png input row stride rs1 = ww * nc1; // png input row stride
if (bpc == 16) rs1 = rs1 * 2; if (bpc == 16) rs1 = rs1 * 2;
cc = imagesize(hh,rs1,1,1); cc = imagesize(hh,rs1,1,1);
if (! cc) goto errret; if (! cc) goto errret;
pngbuff = (uchar *) zmalloc(cc,"PNG_PXM_load"); // png file input buffer pngbuff = (uch *) zmalloc(cc,"PNG_PXM_load"); // png file input buffer
for (row = 0; row < hh; row++) // get all png rows for (row = 0; row < hh; row++) // get all png rows
memcpy(pngbuff+row*rs1,pngrows[row],rs1); memcpy(pngbuff+row*rs1,pngrows[row],rs1);
png_destroy_read_struct(&pngstruct,&pnginfo,0); // release memory png_destroy_read_struct(&pngstruct,&pnginfo,0); // release memory
if (bpc == 8) pixelvert((uint8 *) pngbuff,pxm->pixels,ww,hh,nc1,nc2); // convert pixel data if (bpc == 8) pixelvert((uint8 *) pngbuff,pxm->pixels,ww,hh,nc1,nc2); // convert pixel data
if (bpc == 16) pixelvert((uint16 *) pngbuff,pxm->pixels,ww,hh,nc1,nc2); if (bpc == 16) pixelvert((uint16 *) pngbuff,pxm->pixels,ww,hh,nc1,nc2);
PXM_audit(pxm); // audit/repair PXM_audit(pxm); // audit/repair
skipping to change at line 3405 skipping to change at line 3398
errret: errret:
if (fid && fileno(fid) != -1) fclose(fid); if (fid && fileno(fid) != -1) fclose(fid);
return 0; return 0;
} }
// Write PXB pixmap to PNG file using PNG library. // Write PXB pixmap to PNG file using PNG library.
// File bpc is 8 or 16. // File bpc is 8 or 16.
// returns 0 if OK, +N if error. // returns 0 if OK, +N if error.
int PXB_PNG_save(PXB *pxb, cchar *file, int bpc) int PXB_PNG_save(PXB *pxb, ch *file, int bpc)
{ {
png_structp pngstruct; png_structp pngstruct;
png_infop pnginfo; png_infop pnginfo;
FILE *fid = 0; FILE *fid = 0;
uchar *pngbuff, **pngrows; uch *pngbuff, **pngrows;
int ww, hh, nc1, nc2, rs2, row; int ww, hh, nc1, nc2, rs2, row;
uint cc; uint cc;
if (bpc != 8 && bpc != 16) { if (bpc != 8 && bpc != 16) {
Plog(0,"PNG BPC not 8/16: %s",file); Plog(0,"PNG BPC not 8/16: %s",file);
goto errret; goto errret;
} }
fid = fopen(file,"w"); // open output file fid = fopen(file,"w"); // open output file
if (! fid) { if (! fid) {
skipping to change at line 3451 skipping to change at line 3444
png_set_IHDR(pngstruct,pnginfo,ww,hh,bpc,PNG_COLOR_TYPE_RGB_ALPHA,0,0,0); png_set_IHDR(pngstruct,pnginfo,ww,hh,bpc,PNG_COLOR_TYPE_RGB_ALPHA,0,0,0);
else else
png_set_IHDR(pngstruct,pnginfo,ww,hh,bpc,PNG_COLOR_TYPE_RGB,0,0,0); png_set_IHDR(pngstruct,pnginfo,ww,hh,bpc,PNG_COLOR_TYPE_RGB,0,0,0);
rs2 = ww * nc2; // png row length rs2 = ww * nc2; // png row length
if (bpc == 16) rs2 = rs2 * 2; if (bpc == 16) rs2 = rs2 * 2;
cc = imagesize(hh,rs2,1,1); cc = imagesize(hh,rs2,1,1);
if (! cc) goto errret; if (! cc) goto errret;
pngbuff = (uchar *) zmalloc(cc,"PXB_PNG_save"); // allocate png file data pngbuff = (uch *) zmalloc(cc,"PXB_PNG_save"); // allocate png file data
pngrows = (uchar **) zmalloc(hh * sizeof(char *),"PXB_PNG_save"); // allocate png row pointers pngrows = (uch **) zmalloc(hh * sizeof(ch *),"PXB_PNG_save"); // allocate png row pointers
png_set_rows(pngstruct,pnginfo,pngrows); png_set_rows(pngstruct,pnginfo,pngrows);
for (row = 0; row < hh; row++) // set row pointers to row data for (row = 0; row < hh; row++) // set row pointers to row data
pngrows[row] = pngbuff + row * rs2; pngrows[row] = pngbuff + row * rs2;
if (bpc == 8) pixelvert(pxb->pixels,(uint8 *) pngbuff,ww,hh,nc1,nc2); // convert pixel data if (bpc == 8) pixelvert(pxb->pixels,(uint8 *) pngbuff,ww,hh,nc1,nc2); // convert pixel data
if (bpc == 16) pixelvert(pxb->pixels,(uint16 *) pngbuff,ww,hh,nc1,nc2); if (bpc == 16) pixelvert(pxb->pixels,(uint16 *) pngbuff,ww,hh,nc1,nc2);
png_write_png(pngstruct,pnginfo,PNG_TRANSFORM_SWAP_ENDIAN,0); // write the file png_write_png(pngstruct,pnginfo,PNG_TRANSFORM_SWAP_ENDIAN,0); // write the file
fclose(fid); fclose(fid);
skipping to change at line 3481 skipping to change at line 3474
errret: errret:
if (fid && fileno(fid) != -1) fclose(fid); if (fid && fileno(fid) != -1) fclose(fid);
return 2; return 2;
} }
// Write PXM pixmap to PNG file using PNG library. // Write PXM pixmap to PNG file using PNG library.
// File bpc is 8 or 16. // File bpc is 8 or 16.
// returns 0 if OK, +N if error. // returns 0 if OK, +N if error.
int PXM_PNG_save(PXM *pxm, cchar *file, int bpc) int PXM_PNG_save(PXM *pxm, ch *file, int bpc)
{ {
png_structp pngstruct; png_structp pngstruct;
png_infop pnginfo; png_infop pnginfo;
FILE *fid = 0; FILE *fid = 0;
uchar *pngbuff, **pngrows; uch *pngbuff, **pngrows;
int ww, hh, nc1, nc2, rs2, row; int ww, hh, nc1, nc2, rs2, row;
uint cc; uint cc;
if (bpc != 8 && bpc != 16) { if (bpc != 8 && bpc != 16) {
Plog(0,"PNG BPC not 8/16: %s",file); Plog(0,"PNG BPC not 8/16: %s",file);
goto errret; goto errret;
} }
fid = fopen(file,"w"); // open output file fid = fopen(file,"w"); // open output file
if (! fid) { if (! fid) {
skipping to change at line 3527 skipping to change at line 3520
png_set_IHDR(pngstruct,pnginfo,ww,hh,bpc,PNG_COLOR_TYPE_RGB_ALPHA,0,0,0); png_set_IHDR(pngstruct,pnginfo,ww,hh,bpc,PNG_COLOR_TYPE_RGB_ALPHA,0,0,0);
else else
png_set_IHDR(pngstruct,pnginfo,ww,hh,bpc,PNG_COLOR_TYPE_RGB,0,0,0); png_set_IHDR(pngstruct,pnginfo,ww,hh,bpc,PNG_COLOR_TYPE_RGB,0,0,0);
rs2 = ww * nc2; // png row length rs2 = ww * nc2; // png row length
if (bpc == 16) rs2 = rs2 * 2; if (bpc == 16) rs2 = rs2 * 2;
cc = imagesize(hh,rs2,1,1); cc = imagesize(hh,rs2,1,1);
if (! cc) goto errret; if (! cc) goto errret;
pngbuff = (uchar *) zmalloc(cc,"PXM_PNG_save"); // allocate png file data pngbuff = (uch *) zmalloc(cc,"PXM_PNG_save"); // allocate png file data
pngrows = (uchar **) zmalloc(hh * sizeof(char *),"PXM_PNG_save"); // allocate png row pointers pngrows = (uch **) zmalloc(hh * sizeof(ch *),"PXM_PNG_save"); // allocate png row pointers
png_set_rows(pngstruct,pnginfo,pngrows); png_set_rows(pngstruct,pnginfo,pngrows);
for (row = 0; row < hh; row++) // set row pointers to row data for (row = 0; row < hh; row++) // set row pointers to row data
pngrows[row] = pngbuff + row * rs2; pngrows[row] = pngbuff + row * rs2;
if (bpc == 8) pixelvert(pxm->pixels,(uint8 *) pngbuff,ww,hh,nc1,nc2); // convert pixel data if (bpc == 8) pixelvert(pxm->pixels,(uint8 *) pngbuff,ww,hh,nc1,nc2); // convert pixel data
if (bpc == 16) pixelvert(pxm->pixels,(uint16 *) pngbuff,ww,hh,nc1,nc2); if (bpc == 16) pixelvert(pxm->pixels,(uint16 *) pngbuff,ww,hh,nc1,nc2);
png_write_png(pngstruct,pnginfo,PNG_TRANSFORM_SWAP_ENDIAN,0); // write the file png_write_png(pngstruct,pnginfo,PNG_TRANSFORM_SWAP_ENDIAN,0); // write the file
fclose(fid); fclose(fid);
skipping to change at line 3562 skipping to change at line 3555
/******************************************************************************* * /******************************************************************************* *
HEIC file read functions HEIC file read functions
(write functions are not implemented) (write functions are not implemented)
******************************************************************************** */ ******************************************************************************** */
// Load PXB pixmap from HEIC file using HEIC library (heif-convert). // Load PXB pixmap from HEIC file using HEIC library (heif-convert).
// Crutch: convert .heic file to .jpg and load .jpg file. // Crutch: convert .heic file to .jpg and load .jpg file.
// f_load_bpc = 8 // f_load_bpc = 8
PXB * HEIC_PXB_load(cchar *file, int size) PXB * HEIC_PXB_load(ch *file, int size)
{ {
char *jpegfile = 0, *jpegfix = 0; ch *jpegfile = 0, *jpegfix = 0;
char *pp; ch *pp;
PXB *pxb; PXB *pxb;
static int ftf = 1; static int ftf = 1;
cchar *installmess = ".heic files not supported (install heif_convert)" ; ch *installmess = ".heic files not supported (install heif_convert)";
if (! Fheif) { if (! Fheif) {
if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); } if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); }
return 0; return 0;
} }
if (! regfile(file)) return 0; // no print error if (! regfile(file)) return 0; // no print error
jpegfile = zstrdup(file,"HEIC_PXB_load",8); // file.heic >> file.jpg jpegfile = zstrdup(file,"HEIC_PXB_load",8); // file.heic >> file.jpg
pp = strrchr(jpegfile,'.'); pp = strrchr(jpegfile,'.');
if (! pp) goto errret; if (! pp) goto errret;
strcpy(pp,".jpg"); strcpy(pp,".jpg");
zshell("log","heif-convert -q %d \"%s\" \"%s\" >/dev/null ", // convert to .jpg zshell(0,"heif-convert -q %d \"%s\" \"%s\" >/dev/null ", // convert to .jpg
jpeg_def_quality, file, jpegfile); jpeg_def_quality, file, jpegfile);
if (! regfile(jpegfile)) { if (! regfile(jpegfile)) {
jpegfix = zstrdup(jpegfile,"HEIC_PXB_load",8); // failed, may have multiple output files jpegfix = zstrdup(jpegfile,"HEIC_PXB_load",8); // failed, may have multiple output files
pp = strrchr(jpegfix,'.'); // file-1.jpg, file-2.jpg, etc. pp = strrchr(jpegfix,'.'); // file-1.jpg, file-2.jpg, etc.
strcpy(pp,"-1.jpg"); strcpy(pp,"-1.jpg");
if (! regfile(jpegfix)) goto errret; if (! regfile(jpegfix)) goto errret;
rename(jpegfix,jpegfile); // if file-1.jpg, rename to file.jpg rename(jpegfix,jpegfile); // if file-1.jpg, rename to file.jpg
zfree(jpegfix); // (file-2.jpg etc. remain) zfree(jpegfix); // (file-2.jpg etc. remain)
} }
skipping to change at line 3612 skipping to change at line 3605
if (jpegfile) remove(jpegfile); if (jpegfile) remove(jpegfile);
if (jpegfile) zfree(jpegfile); if (jpegfile) zfree(jpegfile);
if (jpegfix) zfree(jpegfix); if (jpegfix) zfree(jpegfix);
return 0; return 0;
} }
// Load PXM pixmap from HEIC file using HEIC library (heif-convert). // Load PXM pixmap from HEIC file using HEIC library (heif-convert).
// Crutch: convert .heic file to .jpg and load .jpg file. // Crutch: convert .heic file to .jpg and load .jpg file.
// f_load_bpc = 8 // f_load_bpc = 8
PXM * HEIC_PXM_load(cchar *file) PXM * HEIC_PXM_load(ch *file)
{ {
char *jpegfile = 0, *jpegfix = 0; ch *jpegfile = 0, *jpegfix = 0;
char *pp; ch *pp;
PXM *pxm; PXM *pxm;
static int ftf = 1; static int ftf = 1;
cchar *installmess = ".heic files not supported (install heif_convert)" ; ch *installmess = ".heic files not supported (install heif_convert)";
if (! Fheif) { if (! Fheif) {
if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); } if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); }
return 0; return 0;
} }
if (! regfile(file)) return 0; // no print error if (! regfile(file)) return 0; // no print error
jpegfile = zstrdup(file,"HEIC_PXM_load",8); jpegfile = zstrdup(file,"HEIC_PXM_load",8);
pp = strrchr(jpegfile,'.'); pp = strrchr(jpegfile,'.');
if (! pp) goto errret; if (! pp) goto errret;
strcpy(pp,".jpg"); strcpy(pp,".jpg");
zshell("log","heif-convert -q %d \"%s\" \"%s\" >/dev/null ", zshell(0,"heif-convert -q %d \"%s\" \"%s\" >/dev/null ",
jpeg_def_quality, file, jpegfile); jpeg_def_quality, file, jpegfile);
if (! regfile(jpegfile)) { if (! regfile(jpegfile)) {
jpegfix = zstrdup(jpegfile,"HEIC_PXM_load",8); jpegfix = zstrdup(jpegfile,"HEIC_PXM_load",8);
pp = strrchr(jpegfix,'.'); pp = strrchr(jpegfix,'.');
strcpy(pp,"-1.jpg"); strcpy(pp,"-1.jpg");
if (! regfile(jpegfix)) goto errret; if (! regfile(jpegfix)) goto errret;
rename(jpegfix,jpegfile); rename(jpegfix,jpegfile);
zfree(jpegfix); zfree(jpegfix);
} }
skipping to change at line 3657 skipping to change at line 3650
zfree(jpegfile); zfree(jpegfile);
return pxm; return pxm;
errret: errret:
if (jpegfile) remove(jpegfile); if (jpegfile) remove(jpegfile);
if (jpegfile) zfree(jpegfile); if (jpegfile) zfree(jpegfile);
if (jpegfix) zfree(jpegfix); if (jpegfix) zfree(jpegfix);
return 0; return 0;
} }
int PXB_HEIC_save(PXB *pxb, cchar *file) int PXB_HEIC_save(PXB *pxb, ch *file)
{ {
zmessageACK(Mwin,"save to .heic file not supported"); zmessageACK(Mwin,"save to .heic file not supported");
return 0; return 0;
} }
int PXM_HEIC_save(PXM *pxm, cchar *file) int PXM_HEIC_save(PXM *pxm, ch *file)
{ {
zmessageACK(Mwin,"save to .heic file not supported"); zmessageACK(Mwin,"save to .heic file not supported");
return 0; return 0;
} }
/******************************************************************************* * /******************************************************************************* *
JP2 file read functions JP2 file read functions
(write functions are not implemented) (write functions are not implemented)
******************************************************************************** */ ******************************************************************************** */
// Load PXB pixmap from JP2 file using jpeg2000 utility (opj_decompress). // Load PXB pixmap from JP2 file using jpeg2000 utility (opj_decompress).
// Crutch: convert .jp2 file to .tif and load .tif file. // Crutch: convert .jp2 file to .tif and load .tif file.
// f_load_bpc = 8 // f_load_bpc = 8
PXB * JP2_PXB_load(cchar *file) PXB * JP2_PXB_load(ch *file)
{ {
int err; int err;
char *tiffile = 0; ch *tiffile = 0;
char *pp; ch *pp;
PXB *pxb; PXB *pxb;
static int ftf = 1; static int ftf = 1;
cchar *installmess = ".jp2 files not supported (install opj_decompress) "; ch *installmess = ".jp2 files not supported (install opj_decompress) ";
if (! Fjp2) { if (! Fjp2) {
if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); } if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); }
return 0; return 0;
} }
if (! Fjp2) { if (! Fjp2) {
zmessageACK(Mwin,"JP2 files not supported"); zmessageACK(Mwin,"JP2 files not supported");
return 0; return 0;
} }
if (! regfile(file)) return 0; // no print error if (! regfile(file)) return 0; // no print error
tiffile = zstrdup(file,"JP2_PXB_load",8); // file.jp2 >> file.tif tiffile = zstrdup(file,"JP2_PXB_load",8); // file.jp2 >> file.tif
pp = strrchr(tiffile,'.'); pp = strrchr(tiffile,'.');
if (! pp) goto errret; if (! pp) goto errret;
strcpy(pp,".tif"); strcpy(pp,".tif");
err = zshell("log","opj_decompress -i \"%s\" -o \"%s\" >/dev/null 2>1",file,t iffile); err = zshell(0,"opj_decompress -i \"%s\" -o \"%s\" >/dev/null 2>1",file,tiffi le);
if (err) goto errret; if (err) goto errret;
if (! regfile(tiffile)) goto errret; if (! regfile(tiffile)) goto errret;
pxb = TIFF_PXB_load(tiffile); // make PXB from tif file pxb = TIFF_PXB_load(tiffile); // make PXB from tif file
remove(tiffile); remove(tiffile);
zfree(tiffile); zfree(tiffile);
return pxb; return pxb;
errret: errret:
if (tiffile) remove(tiffile); if (tiffile) remove(tiffile);
if (tiffile) zfree(tiffile); if (tiffile) zfree(tiffile);
return 0; return 0;
} }
// Load PXM pixmap from JP2 file using jpeg2000 utility (opj_decompress). // Load PXM pixmap from JP2 file using jpeg2000 utility (opj_decompress).
// Crutch: convert .jp2 file to .tif and load .tif file. // Crutch: convert .jp2 file to .tif and load .tif file.
// f_load_bpc = 8 or 16, depending on .jp2 file // f_load_bpc = 8 or 16, depending on .jp2 file
PXM * JP2_PXM_load(cchar *file) PXM * JP2_PXM_load(ch *file)
{ {
int err; int err;
char *tiffile = 0; ch *tiffile = 0;
char *pp; ch *pp;
PXM *pxm = 0; PXM *pxm = 0;
static int ftf = 1; static int ftf = 1;
cchar *installmess = ".jp2 files not supported (install opj_decompress) "; ch *installmess = ".jp2 files not supported (install opj_decompress) ";
if (! Fjp2) { if (! Fjp2) {
if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); } if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); }
return 0; return 0;
} }
if (! regfile(file)) return 0; // no print error if (! regfile(file)) return 0; // no print error
tiffile = zstrdup(file,"JP2_PXM_load",8); // file.jp2 >> file.tif tiffile = zstrdup(file,"JP2_PXM_load",8); // file.jp2 >> file.tif
pp = strrchr(tiffile,'.'); pp = strrchr(tiffile,'.');
if (! pp) goto errret; if (! pp) goto errret;
strcpy(pp,".tif"); strcpy(pp,".tif");
err = zshell("log","opj_decompress -i \"%s\" -o \"%s\" >/dev/null 2>1",file,t iffile); err = zshell(0,"opj_decompress -i \"%s\" -o \"%s\" >/dev/null 2>1",file,tiffi le);
if (err) goto errret; if (err) goto errret;
if (! regfile(tiffile)) goto errret; if (! regfile(tiffile)) goto errret;
pxm = TIFF_PXM_load(tiffile); // make PXM from tif file pxm = TIFF_PXM_load(tiffile); // make PXM from tif file
remove(tiffile); remove(tiffile);
zfree(tiffile); zfree(tiffile);
return pxm; return pxm;
errret: errret:
if (tiffile) remove(tiffile); if (tiffile) remove(tiffile);
if (tiffile) zfree(tiffile); if (tiffile) zfree(tiffile);
return 0; return 0;
} }
int PXB_JP2_save(PXB *pxb, cchar *file) int PXB_JP2_save(PXB *pxb, ch *file)
{ {
zmessageACK(Mwin,"save to .jp2 file not supported"); zmessageACK(Mwin,"save to .jp2 file not supported");
return 0; return 0;
} }
int PXM_JP2_save(PXM *pxm, cchar *file) int PXM_JP2_save(PXM *pxm, ch *file)
{ {
zmessageACK(Mwin,"save to .jp2 file not supported"); zmessageACK(Mwin,"save to .jp2 file not supported");
return 0; return 0;
} }
/******************************************************************************* * /******************************************************************************* *
WEBP file read functions WEBP file read functions
(write functions are not implemented) (write functions are not implemented)
******************************************************************************** */ ******************************************************************************** */
// Load PXB pixmap from WEBP file using dwebp utility (webp package). // Load PXB pixmap from WEBP file using dwebp utility (webp package).
// Crutch: convert .webp file to .tif and load .tif file. // Crutch: convert .webp file to .tif and load .tif file.
// f_load_bpc = 8 // f_load_bpc = 8
PXB * WEBP_PXB_load(cchar *file) PXB * WEBP_PXB_load(ch *file)
{ {
int err; int err;
char *tiffile = 0; ch *tiffile = 0;
char *pp; ch *pp;
PXB *pxb; PXB *pxb;
static int ftf = 1; static int ftf = 1;
cchar *installmess = ".webp files not supported (install dwebp)"; ch *installmess = ".webp files not supported (install dwebp)";
if (! Fwebp) { if (! Fwebp) {
if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); } if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); }
return 0; return 0;
} }
if (! regfile(file)) return 0; // no print error if (! regfile(file)) return 0; // no print error
tiffile = zstrdup(file,"WEBP_PXB_load",8); // file.webp >> file.tif tiffile = zstrdup(file,"WEBP_PXB_load",8); // file.webp >> file.tif
pp = strrchr(tiffile,'.'); pp = strrchr(tiffile,'.');
if (! pp) goto errret; if (! pp) goto errret;
strcpy(pp,".tif"); strcpy(pp,".tif");
err = zshell("log","dwebp -quiet -tiff \"%s\" -o \"%s\" ",file,tiffile); err = zshell(0,"dwebp -quiet -tiff \"%s\" -o \"%s\" ",file,tiffile);
if (err) goto errret; if (err) goto errret;
if (! regfile(tiffile)) goto errret; if (! regfile(tiffile)) goto errret;
pxb = TIFF_PXB_load(tiffile); // make PXB from tif file pxb = TIFF_PXB_load(tiffile); // make PXB from tif file
remove(tiffile); remove(tiffile);
zfree(tiffile); zfree(tiffile);
return pxb; return pxb;
errret: errret:
if (tiffile) remove(tiffile); if (tiffile) remove(tiffile);
if (tiffile) zfree(tiffile); if (tiffile) zfree(tiffile);
return 0; return 0;
} }
// Load PXM pixmap from WEBP file using jpeg2000 utility (opj_decompress). // Load PXM pixmap from WEBP file using jpeg2000 utility (opj_decompress).
// Crutch: convert .webp file to .tif and load .tif file. // Crutch: convert .webp file to .tif and load .tif file.
// f_load_bpc = 8 or 16, depending on .webp file // f_load_bpc = 8 or 16, depending on .webp file
PXM * WEBP_PXM_load(cchar *file) PXM * WEBP_PXM_load(ch *file)
{ {
int err; int err;
char *tiffile = 0; ch *tiffile = 0;
char *pp; ch *pp;
PXM *pxm = 0; PXM *pxm = 0;
static int ftf = 1; static int ftf = 1;
cchar *installmess = ".webp files not supported (install dwebp)"; ch *installmess = ".webp files not supported (install dwebp)";
if (! Fwebp) { if (! Fwebp) {
if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); } if (ftf) { ftf = 0; zmessageACK(Mwin,installmess); }
return 0; return 0;
} }
if (! regfile(file)) return 0; // no print error if (! regfile(file)) return 0; // no print error
tiffile = zstrdup(file,"WEBP_PXM_load",8); // file.webp >> file.tif tiffile = zstrdup(file,"WEBP_PXM_load",8); // file.webp >> file.tif
pp = strrchr(tiffile,'.'); pp = strrchr(tiffile,'.');
if (! pp) goto errret; if (! pp) goto errret;
strcpy(pp,".tif"); strcpy(pp,".tif");
err = zshell("log","dwebp -quiet -tiff \"%s\" -o \"%s\" ",file,tiffile); err = zshell(0,"dwebp -quiet -tiff \"%s\" -o \"%s\" ",file,tiffile);
if (err) goto errret; if (err) goto errret;
if (! regfile(tiffile)) goto errret; if (! regfile(tiffile)) goto errret;
pxm = TIFF_PXM_load(tiffile); // make PXM from tif file pxm = TIFF_PXM_load(tiffile); // make PXM from tif file
remove(tiffile); remove(tiffile);
zfree(tiffile); zfree(tiffile);
return pxm; return pxm;
errret: errret:
if (tiffile) remove(tiffile); if (tiffile) remove(tiffile);
if (tiffile) zfree(tiffile); if (tiffile) zfree(tiffile);
return 0; return 0;
} }
int PXB_WEBP_save(PXB *pxb, cchar *file) int PXB_WEBP_save(PXB *pxb, ch *file)
{ {
zmessageACK(Mwin,"save to .webp file not supported"); zmessageACK(Mwin,"save to .webp file not supported");
return 0; return 0;
} }
int PXM_WEBP_save(PXM *pxm, cchar *file) int PXM_WEBP_save(PXM *pxm, ch *file)
{ {
zmessageACK(Mwin,"save to .webp file not supported"); zmessageACK(Mwin,"save to .webp file not supported");
return 0; return 0;
} }
/******************************************************************************* * /******************************************************************************* *
MPO file read functions MPO file read functions
(write functions are not implemented) (write functions are not implemented)
******************************************************************************** */ ******************************************************************************** */
// Extract left image from .MPO file, load PXB pixmap from the left image. // Extract left image from .MPO file, load PXB pixmap from the left image.
// Optional size arg: target size for thumbnail. Use 0 for full size image. // Optional size arg: target size for thumbnail. Use 0 for full size image.
// f_load_bpc = 8 // f_load_bpc = 8
PXB * MPO_PXB_load(cchar *file, int size) PXB * MPO_PXB_load(ch *file, int size)
{ {
char *jpegfile = 0; ch *jpegfile = 0;
char *pp; ch *pp;
PXB *pxb = 0; PXB *pxb = 0;
if (! regfile(file)) return 0; // no print error if (! regfile(file)) return 0; // no print error
jpegfile = zstrdup(file,"MPO_PXB_load",8); // construct filename.jpg jpegfile = zstrdup(file,"MPO_PXB_load",8); // construct filename.jpg
pp = strrchr(jpegfile,'.'); pp = strrchr(jpegfile,'.');
if (! pp) goto errret; if (! pp) goto errret;
strcpy(pp,".jpg"); strcpy(pp,".jpg");
zshell("log","exiftool \"%s\" -mpimage2 -b > \"%s\" ",file,jpegfile); // left image (default) zshell(0,"exiftool \"%s\" -mpimage2 -b > \"%s\" ",file,jpegfile); // left image (default)
if (! regfile(jpegfile)) goto errret; if (! regfile(jpegfile)) goto errret;
pxb = JPG_PXB_load(jpegfile,size); // make PXB pxb = JPG_PXB_load(jpegfile,size); // make PXB
errret: errret:
if (jpegfile) remove(jpegfile); // remove jpeg file if (jpegfile) remove(jpegfile); // remove jpeg file
if (jpegfile) zfree(jpegfile); if (jpegfile) zfree(jpegfile);
return pxb; return pxb;
} }
// Extract left image from .MPO file, load PXM pixmap from the left image. // Extract left image from .MPO file, load PXM pixmap from the left image.
// f_load_bpc = 8 // f_load_bpc = 8
PXM * MPO_PXM_load(cchar *file) PXM * MPO_PXM_load(ch *file)
{ {
char *jpegfile = 0; ch *jpegfile = 0;
char *pp; ch *pp;
PXM *pxm = 0; PXM *pxm = 0;
if (! regfile(file)) return 0; // no print error if (! regfile(file)) return 0; // no print error
jpegfile = zstrdup(file,"MPO_PXM_load",8); // construct filename.jpg jpegfile = zstrdup(file,"MPO_PXM_load",8); // construct filename.jpg
pp = strrchr(jpegfile,'.'); pp = strrchr(jpegfile,'.');
if (! pp) goto errret; if (! pp) goto errret;
strcpy(pp,".jpg"); strcpy(pp,".jpg");
zshell("log","exiftool \"%s\" -mpimage2 -b > \"%s\" ",file,jpegfile); // left image (default) zshell(0,"exiftool \"%s\" -mpimage2 -b > \"%s\" ",file,jpegfile); // left image (default)
if (! regfile(jpegfile)) goto errret; if (! regfile(jpegfile)) goto errret;
pxm = JPG_PXM_load(jpegfile); // make PXM pxm = JPG_PXM_load(jpegfile); // make PXM
errret: errret:
if (jpegfile) remove(jpegfile); // remove jpeg file if (jpegfile) remove(jpegfile); // remove jpeg file
if (jpegfile) zfree(jpegfile); if (jpegfile) zfree(jpegfile);
return pxm; return pxm;
} }
// MPO file save functions - not implemented // MPO file save functions - not implemented
int PXB_MPO_save(PXB *pxb, cchar *file) int PXB_MPO_save(PXB *pxb, ch *file)
{ {
zmessageACK(Mwin,"save to .MPO file not supported"); zmessageACK(Mwin,"save to .MPO file not supported");
return 0; return 0;
} }
int PXM_MPO_save(PXM *pxm, cchar *file) int PXM_MPO_save(PXM *pxm, ch *file)
{ {
zmessageACK(Mwin,"save to .MPO file not supported"); zmessageACK(Mwin,"save to .MPO file not supported");
return 0; return 0;
} }
/******************************************************************************* * /******************************************************************************* *
Other file types read and write functions (via gdk_pixbuf library) Other file types read and write functions (via gdk_pixbuf library)
******************************************************************************** */ ******************************************************************************** */
// Load PXB pixmap from other file types using the pixbuf library. // Load PXB pixmap from other file types using the pixbuf library.
// bpc = 8. // bpc = 8.
PXB * ANY_PXB_load(cchar *file) PXB * ANY_PXB_load(ch *file)
{ {
GError *gerror = 0; GError *gerror = 0;
PXB *pxb; PXB *pxb;
PIXBUF *pixbuf; PIXBUF *pixbuf;
int ww, hh, px, py, nc1, nc2, ac, rs; int ww, hh, px, py, nc1, nc2, ac, rs;
uint8 *pixels1, *pix1; uint8 *pixels1, *pix1;
uint8 *pixels2, *pix2; uint8 *pixels2, *pix2;
if (! regfile(file)) goto errret; // no print error if (! regfile(file)) goto errret; // no print error
skipping to change at line 4033 skipping to change at line 4026
errret: errret:
Plog(0,"pixbuf read error: %s \n",file); Plog(0,"pixbuf read error: %s \n",file);
if (gerror) Plog(0,"%s \n",gerror->message); if (gerror) Plog(0,"%s \n",gerror->message);
return 0; return 0;
} }
// Load PXM pixmap from other file types using the pixbuf library. // Load PXM pixmap from other file types using the pixbuf library.
// bpc = 8. // bpc = 8.
PXM * ANY_PXM_load(cchar *file) PXM * ANY_PXM_load(ch *file)
{ {
GError *gerror = 0; GError *gerror = 0;
PXM *pxm; PXM *pxm;
PIXBUF *pixbuf; PIXBUF *pixbuf;
int ww, hh, px, py, nc1, nc2, ac, rs; int ww, hh, px, py, nc1, nc2, ac, rs;
uint8 *pixels1, *pix1; uint8 *pixels1, *pix1;
float *pixels2, *pix2; float *pixels2, *pix2;
if (! regfile(file)) goto errret; // no print error if (! regfile(file)) goto errret; // no print error
skipping to change at line 4109 skipping to change at line 4102
Plog(0,"pixbuf read error: %s \n",file); Plog(0,"pixbuf read error: %s \n",file);
if (gerror) Plog(0,"%s \n",gerror->message); if (gerror) Plog(0,"%s \n",gerror->message);
return 0; return 0;
} }
/******************************************************************************* * /******************************************************************************* *
RAW file read functions. RAW file read functions.
There are no write functions. There are no write functions.
******************************************************************************** */ ******************************************************************************** */
int raw_match_thumb_color(cchar *rawfile, PXM *pxm); int raw_match_thumb_color(ch *rawfile, PXM *pxm);
int raw_match_thumb_color(cchar *rawfile, PXB *pxb); int raw_match_thumb_color(ch *rawfile, PXB *pxb);
// RAW file to PXB pixmap (pixbuf, 8-bit color) // RAW file to PXB pixmap (pixbuf, 8-bit color)
PXB * RAW_PXB_load(cchar *rawfile, int autobright, int matchthumb) PXB * RAW_PXB_load(ch *rawfile, int autobright, int matchthumb)
{ {
PXB *pxb = 0; PXB *pxb = 0;
if (Frawloader == 1) pxb = RAW_PXB_load_dcraw(rawfile,autobright); if (Frawloader == 1) pxb = RAW_PXB_load_dcraw(rawfile,autobright);
if (Frawloader == 2) pxb = RAW_PXB_load_RT(rawfile,autobright); if (Frawloader == 2) pxb = RAW_PXB_load_RT(rawfile,autobright);
if (Frawloader == 3) pxb = RAW_PXB_load_DT(rawfile,autobright); if (Frawloader == 3) pxb = RAW_PXB_load_DT(rawfile,autobright);
if (Frawloader == 4) pxb = RAW_PXB_load_custom(rawfile,autobright); if (Frawloader == 4) pxb = RAW_PXB_load_custom(rawfile,autobright);
if (! pxb) return 0; if (! pxb) return 0;
if (matchthumb) raw_match_thumb_color(rawfile,pxb); if (matchthumb) raw_match_thumb_color(rawfile,pxb);
return pxb; return pxb;
} }
// RAW file to PXM pixmap (float color) // RAW file to PXM pixmap (float color)
PXM * RAW_PXM_load(cchar *rawfile, int autobright, int matchthumb) PXM * RAW_PXM_load(ch *rawfile, int autobright, int matchthumb)
{ {
PXM *pxm = 0; PXM *pxm = 0;
if (Frawloader == 1) pxm = RAW_PXM_load_dcraw(rawfile,autobright); if (Frawloader == 1) pxm = RAW_PXM_load_dcraw(rawfile,autobright);
if (Frawloader == 2) pxm = RAW_PXM_load_RT(rawfile,autobright); if (Frawloader == 2) pxm = RAW_PXM_load_RT(rawfile,autobright);
if (Frawloader == 3) pxm = RAW_PXM_load_DT(rawfile,autobright); if (Frawloader == 3) pxm = RAW_PXM_load_DT(rawfile,autobright);
if (Frawloader == 4) pxm = RAW_PXM_load_custom(rawfile,autobright); if (Frawloader == 4) pxm = RAW_PXM_load_custom(rawfile,autobright);
if (! pxm) return 0; if (! pxm) return 0;
if (matchthumb) raw_match_thumb_color(rawfile,pxm); if (matchthumb) raw_match_thumb_color(rawfile,pxm);
return pxm; return pxm;
} }
// RAW file to PXB pixmap (pixbuf, 8-bit color, dcraw) // RAW file to PXB pixmap (pixbuf, 8-bit color, dcraw)
PXB * RAW_PXB_load_dcraw(cchar *rawfile, int autobright) PXB * RAW_PXB_load_dcraw(ch *rawfile, int autobright)
{ {
int err; int err;
char *tiffile, *pp; ch *tiffile, *pp;
PXB *pxb; PXB *pxb;
cchar *command; ch *command;
cchar *command1 = "dcraw -w -T -q 0 \"%s\" "; ch *command1 = "dcraw -w -T -q 0 \"%s\" ";
// tiff-8 output // tiff-8 output
cchar *command2 = "dcraw -w -T -q 0 -W \"%s\" "; ch *command2 = "dcraw -w -T -q 0 -W \"%s\" ";
if (autobright) command = command1; if (autobright) command = command1;
else command = command2; else command = command2;
pp = zescape_quotes(rawfile); // make tiff file from raw file pp = zescape_quotes(rawfile); // make tiff file from raw file
err = zshell("log",command,pp); err = zshell(0,command,pp);
zfree(pp); zfree(pp);
if (err) return 0; if (err) return 0;
tiffile = zstrdup(rawfile,"RAW_PXB_load",8); // tiff file name = rawfile.tiff tiffile = zstrdup(rawfile,"RAW_PXB_load",8); // tiff file name = rawfile.tiff
pp = strrchr(tiffile,'/'); pp = strrchr(tiffile,'/');
pp = strrchr(pp,'.'); pp = strrchr(pp,'.');
if (! pp) pp = tiffile + strlen(tiffile); if (! pp) pp = tiffile + strlen(tiffile);
strcpy(pp,".tiff"); strcpy(pp,".tiff");
pxb = TIFF_PXB_load(tiffile); // make raw PXB from tiff file pxb = TIFF_PXB_load(tiffile); // make raw PXB from tiff file
remove(tiffile); remove(tiffile);
zfree(tiffile); zfree(tiffile);
return pxb; return pxb;
} }
// RAW file to PXB pixmap (pixbuf, 8-bit color, dcraw) // RAW file to PXB pixmap (pixbuf, 8-bit color, dcraw)
// use 1/2 size output file for faster thumbnail creation // use 1/2 size output file for faster thumbnail creation
PXB * RAW_PXB_load_dcraw_half(cchar *rawfile) PXB * RAW_PXB_load_dcraw_half(ch *rawfile)
{ {
int err; int err;
char *tiffile, *pp; ch *tiffile, *pp;
PXB *pxb; PXB *pxb;
cchar *command = "dcraw -w -T -h \"%s\" "; // -h (half size) ch *command = "dcraw -w -T -h \"%s\" "; // -h (half size)
zadd_locked(Ffuncbusy,+1); zadd_locked(Ffuncbusy,+1);
pp = zescape_quotes(rawfile); // make tiff file from raw file pp = zescape_quotes(rawfile); // make tiff file from raw file
err = zshell(0,command,pp); err = zshell(0,command,pp);
zfree(pp); zfree(pp);
if (err) { if (err) {
zadd_locked(Ffuncbusy,-1); zadd_locked(Ffuncbusy,-1);
return 0; return 0;
} }
skipping to change at line 4215 skipping to change at line 4208
remove(tiffile); remove(tiffile);
zfree(tiffile); zfree(tiffile);
zadd_locked(Ffuncbusy,-1); zadd_locked(Ffuncbusy,-1);
return pxb; return pxb;
} }
// RAW file to PXM pixmap (float color, dcraw) // RAW file to PXM pixmap (float color, dcraw)
PXM * RAW_PXM_load_dcraw(cchar *rawfile, int autobright) PXM * RAW_PXM_load_dcraw(ch *rawfile, int autobright)
{ {
int err; int err;
char *tiffile, *pp; ch *tiffile, *pp;
PXM *pxm; PXM *pxm;
cchar *command; ch *command;
cchar *command1 = "dcraw -w -T -6 -q 0 \"%s\" "; ch *command1 = "dcraw -w -T -6 -q 0 \"%s\" ";
// tiff-16 output // tiff-16 output
cchar *command2 = "dcraw -w -T -6 -q 0 -W \"%s\" "; ch *command2 = "dcraw -w -T -6 -q 0 -W \"%s\" ";
if (autobright) command = command1; if (autobright) command = command1;
else command = command2; else command = command2;
pp = zescape_quotes(rawfile); // make tiff file from raw file pp = zescape_quotes(rawfile); // make tiff file from raw file
err = zshell("log",command,pp); err = zshell(0,command,pp);
zfree(pp); zfree(pp);
if (err) return 0; if (err) return 0;
tiffile = zstrdup(rawfile,"RAW_PXM_load",8); // tiff file name = rawfile.tiff tiffile = zstrdup(rawfile,"RAW_PXM_load",8); // tiff file name = rawfile.tiff
pp = strrchr(tiffile,'/'); pp = strrchr(tiffile,'/');
pp = strrchr(pp,'.'); pp = strrchr(pp,'.');
if (! pp) pp = tiffile + strlen(tiffile); if (! pp) pp = tiffile + strlen(tiffile);
strcpy(pp,".tiff"); strcpy(pp,".tiff");
pxm = TIFF_PXM_load(tiffile); // make raw PXM from tiff file pxm = TIFF_PXM_load(tiffile); // make raw PXM from tiff file
remove(tiffile); remove(tiffile);
zfree(tiffile); zfree(tiffile);
return pxm; return pxm;
} }
// RAW file to PXB pixmap (pixbuf, 8-bit color, raw therapee) // RAW file to PXB pixmap (pixbuf, 8-bit color, raw therapee)
PXB * RAW_PXB_load_RT(cchar *rawfile, int autobright) PXB * RAW_PXB_load_RT(ch *rawfile, int autobright)
{ {
int err; int err;
PXB *pxb = 0; PXB *pxb = 0;
char *pp, *tiffile; ch *pp, *tiffile;
cchar *command; ch *command;
cchar *command1 = "rawtherapee-cli -q -d -t -b16 -Y -c \"%s\" >/dev/null"; ch *command1 = "rawtherapee-cli -q -d -t -b16 -Y -c \"%s\" >/dev/null";
cchar *command2 = "rawtherapee-cli -q -t -b16 -Y -c \"%s\" >/dev/null"; ch *command2 = "rawtherapee-cli -q -t -b16 -Y -c \"%s\" >/dev/null";
if (autobright) command = command1; if (autobright) command = command1;
else command = command2; else command = command2;
pp = zescape_quotes(rawfile); // use rawtherapee pp = zescape_quotes(rawfile); // use rawtherapee
err = zshell("log",command,pp); // convert to rawfile.tif err = zshell(0,command,pp); // convert to rawfile.tif
zfree(pp); zfree(pp);
if (err) return 0; if (err) return 0;
tiffile = zstrdup(rawfile,"RAW_PXB_load",8); // tiff file name = rawfile.tif tiffile = zstrdup(rawfile,"RAW_PXB_load",8); // tiff file name = rawfile.tif
pp = strrchr(tiffile,'/'); pp = strrchr(tiffile,'/');
pp = strrchr(pp,'.'); pp = strrchr(pp,'.');
if (! pp) pp = tiffile + strlen(tiffile); if (! pp) pp = tiffile + strlen(tiffile);
strcpy(pp,".tif"); strcpy(pp,".tif");
pxb = TIFF_PXB_load(tiffile); pxb = TIFF_PXB_load(tiffile);
remove(tiffile); remove(tiffile);
zfree(tiffile); zfree(tiffile);
return pxb; return pxb;
} }
// RAW file to PXM pixmap (float color, raw therapee) // RAW file to PXM pixmap (float color, raw therapee)
PXM * RAW_PXM_load_RT(cchar *rawfile, int autobright) PXM * RAW_PXM_load_RT(ch *rawfile, int autobright)
{ {
int err; int err;
PXM *pxm = 0; PXM *pxm = 0;
char *pp, *tiffile; ch *pp, *tiffile;
cchar *command; ch *command;
cchar *command1 = "rawtherapee-cli -q -d -t -b16 -Y -c \"%s\" >/dev/null"; ch *command1 = "rawtherapee-cli -q -d -t -b16 -Y -c \"%s\" >/dev/null";
cchar *command2 = "rawtherapee-cli -q -t -b16 -Y -c \"%s\" >/dev/null"; ch *command2 = "rawtherapee-cli -q -t -b16 -Y -c \"%s\" >/dev/null";
if (autobright) command = command1; if (autobright) command = command1;
else command = command2; else command = command2;
pp = zescape_quotes(rawfile); // use rawtherapee pp = zescape_quotes(rawfile); // use rawtherapee
err = zshell("log",command,pp); // convert to rawfile.tif err = zshell(0,command,pp); // convert to rawfile.tif
zfree(pp); zfree(pp);
if (err) return 0; if (err) return 0;
tiffile = zstrdup(rawfile,"RAW_PXM_load",8); // tiff file name = rawfile.tif tiffile = zstrdup(rawfile,"RAW_PXM_load",8); // tiff file name = rawfile.tif
pp = strrchr(tiffile,'/'); pp = strrchr(tiffile,'/');
pp = strrchr(pp,'.'); pp = strrchr(pp,'.');
if (! pp) pp = tiffile + strlen(tiffile); if (! pp) pp = tiffile + strlen(tiffile);
strcpy(pp,".tif"); strcpy(pp,".tif");
pxm = TIFF_PXM_load(tiffile); pxm = TIFF_PXM_load(tiffile);
remove(tiffile); remove(tiffile);
zfree(tiffile); zfree(tiffile);
return pxm; return pxm;
} }
// RAW file to PXB pixmap (pixbuf, 8-bit color, darktable) // RAW file to PXB pixmap (pixbuf, 8-bit color, darktable)
PXB * RAW_PXB_load_DT(cchar *rawfile, int autobright) PXB * RAW_PXB_load_DT(ch *rawfile, int autobright)
{ {
int err; int err;
PXB *pxb = 0; PXB *pxb = 0;
char *pp, *pp1, *pp2; ch *pp, *pp1, *pp2;
cchar *command1 = "darktable-cli --upscale 1 \"%s\" \"%s\" >/dev/null"; ch *command1 = "darktable-cli --upscale 1 \"%s\" \"%s\" >/dev/null";
cchar *command2 = "darktable-cli \"%s\" \"%s\" >/dev/null"; ch *command2 = "darktable-cli \"%s\" \"%s\" >/dev/null";
cchar *command; ch *command;
if (autobright) command = command1; if (autobright) command = command1;
else command = command2; else command = command2;
pp1 = zescape_quotes(rawfile); // construct <rawfile>.jpg pp1 = zescape_quotes(rawfile); // construct <rawfile>.jpg
pp2 = zstrdup(pp1,"RAW_PXB_load",8); pp2 = zstrdup(pp1,"RAW_PXB_load",8);
pp = strrchr(pp2,'.'); pp = strrchr(pp2,'.');
if (! pp) pp = pp2 + strlen(pp2); if (! pp) pp = pp2 + strlen(pp2);
strcpy(pp,".jpg"); strcpy(pp,".jpg");
err = zshell("log",command,pp1,pp2); // convert to rawfile.jpg err = zshell(0,command,pp1,pp2); // convert to rawfile.jpg
if (err) Plog(0,"RAW conversion failed: %s \n",rawfile); if (err) Plog(0,"RAW conversion failed: %s \n",rawfile);
else pxb = JPG_PXB_load(pp2); // load file to PXB else pxb = JPG_PXB_load(pp2); // load file to PXB
remove(pp2); remove(pp2);
zfree(pp1); zfree(pp1);
zfree(pp2); zfree(pp2);
return pxb; return pxb;
} }
// RAW file to PXM pixmap (float color, darktable) // RAW file to PXM pixmap (float color, darktable)
// (as of Jan 2021 DT cannot convert raw to tiff-16) // (as of Jan 2021 DT cannot convert raw to tiff-16)
PXM * RAW_PXM_load_DT(cchar *rawfile, int autobright) PXM * RAW_PXM_load_DT(ch *rawfile, int autobright)
{ {
int err; int err;
PXM *pxm = 0; PXM *pxm = 0;
char *pp, *pp1, *pp2; ch *pp, *pp1, *pp2;
cchar *command1 = "darktable-cli --upscale 1 \"%s\" \"%s\" >/dev/null"; ch *command1 = "darktable-cli --upscale 1 \"%s\" \"%s\" >/dev/null";
cchar *command2 = "darktable-cli \"%s\" \"%s\" >/dev/null"; ch *command2 = "darktable-cli \"%s\" \"%s\" >/dev/null";
cchar *command; ch *command;
if (autobright) command = command1; if (autobright) command = command1;
else command = command2; else command = command2;
pp1 = zescape_quotes(rawfile); // construct <rawfile>.jpg pp1 = zescape_quotes(rawfile); // construct <rawfile>.jpg
pp2 = zstrdup(pp1,"RAW_PXM_load",8); pp2 = zstrdup(pp1,"RAW_PXM_load",8);
pp = strrchr(pp2,'.'); pp = strrchr(pp2,'.');
if (! pp) pp = pp2 + strlen(pp2); if (! pp) pp = pp2 + strlen(pp2);
strcpy(pp,".jpg"); strcpy(pp,".jpg");
err = zshell("log",command,pp1,pp2); // convert to rawfile.jpg err = zshell(0,command,pp1,pp2); // convert to rawfile.jpg
if (err) Plog(0,"RAW conversion failed: %s \n",rawfile); if (err) Plog(0,"RAW conversion failed: %s \n",rawfile);
else pxm = JPG_PXM_load(pp2); // load file to PXM else pxm = JPG_PXM_load(pp2); // load file to PXM
remove(pp2); remove(pp2);
zfree(pp1); zfree(pp1);
zfree(pp2); zfree(pp2);
return pxm; return pxm;
} }
// RAW file to PXB pixmap (pixbuf, 8-bit color, custom loader) // RAW file to PXB pixmap (pixbuf, 8-bit color, custom loader)
PXB * RAW_PXB_load_custom(cchar *rawfile, int autobright) // 22.35 PXB * RAW_PXB_load_custom(ch *rawfile, int autobright) // 22.35
{ {
PXB *pxb = 0; PXB *pxb = 0;
PXM *pxm = 0; PXM *pxm = 0;
pxm = RAW_PXM_load_custom(rawfile,autobright); pxm = RAW_PXM_load_custom(rawfile,autobright);
if (! pxm) return 0; if (! pxm) return 0;
pxb = PXM_PXB_copy(pxm); pxb = PXM_PXB_copy(pxm);
PXM_free(pxm); PXM_free(pxm);
return pxb; return pxb;
} }
// RAW file to PXM pixmap (float color, custom loader) // RAW file to PXM pixmap (float color, custom loader)
PXM * RAW_PXM_load_custom(cchar *rawfile, int autobright) // 22.35 PXM * RAW_PXM_load_custom(ch *rawfile, int autobright) // 22.35
{ {
int err; int err;
PXM *pxm = 0; PXM *pxm = 0;
char *pp, *tiffile; ch *pp, *tiffile;
pp = zescape_quotes(rawfile); // use custom RAW loader command pp = zescape_quotes(rawfile); // use custom RAW loader command
err = zshell("log",rawcommand,pp); // convert to rawfile.tif err = zshell(0,rawcommand,pp); // convert to rawfile.tif
zfree(pp); zfree(pp);
if (err) return 0; if (err) return 0;
tiffile = zstrdup(rawfile,"RAW_PXM_load",8); // tiff file name = rawfile.tif tiffile = zstrdup(rawfile,"RAW_PXM_load",8); // tiff file name = rawfile.tif
pp = strrchr(tiffile,'/'); pp = strrchr(tiffile,'/');
pp = strrchr(pp,'.'); pp = strrchr(pp,'.');
if (! pp) pp = tiffile + strlen(tiffile); if (! pp) pp = tiffile + strlen(tiffile);
strcpy(pp,".tif"); strcpy(pp,".tif");
pxm = TIFF_PXM_load(tiffile); pxm = TIFF_PXM_load(tiffile);
remove(tiffile); remove(tiffile);
zfree(tiffile); zfree(tiffile);
return pxm; return pxm;
} }
// Create 512x512 PXB for thumbnail from the embedded image in a RAW file // Create 512x512 PXB for thumbnail from the embedded image in a RAW file
PXB * RAW_thumb_pxb(cchar *rawfile) // 22.1 PXB * RAW_thumb_pxb(ch *rawfile) // 22.1
{ {
char *thumbfile = 0, *pp; ch *thumbfile = 0, *pp;
int err, ww, hh, angle = 0; int err, ww, hh, angle = 0;
PXB *Tpxb = 0, *Rpxb = 0; PXB *Tpxb = 0, *Rpxb = 0;
cchar *exifkey[1] = { exif_orientation_key }; ch *metakey[1] = { meta_orientation_key };
char *exifdata[1] = { 0 }, orientation = 0; ch *metadata[1] = { 0 }, orientation = 0;
pp = zescape_quotes(rawfile); pp = zescape_quotes(rawfile);
err = zshell(0,"dcraw -e \"%s\" ",pp); // get .jpg or .ppm embedded image err = zshell(0,"dcraw -e \"%s\" ",pp); // get .jpg or .ppm embedded image
zfree(pp); zfree(pp);
if (err) goto getraw; // none there if (err) goto getraw; // none there
thumbfile = zstrdup(rawfile,"RAW_thumb_pxb",12); // rawfile.thumb.jpg (or .ppm) thumbfile = zstrdup(rawfile,"RAW_thumb_pxb",12); // rawfile.thumb.jpg (or .ppm)
pp = strrchr(thumbfile,'/'); pp = strrchr(thumbfile,'/');
pp = strrchr(pp,'.'); pp = strrchr(pp,'.');
if (! pp) pp = thumbfile + strlen(thumbfile); if (! pp) pp = thumbfile + strlen(thumbfile);
skipping to change at line 4449 skipping to change at line 4442
strcpy(pp+6,".ppm"); strcpy(pp+6,".ppm");
Tpxb = ANY_PXB_load(thumbfile); Tpxb = ANY_PXB_load(thumbfile);
} }
if (! Tpxb) { // embedded image not usable if (! Tpxb) { // embedded image not usable
remove(thumbfile); remove(thumbfile);
zfree(thumbfile); zfree(thumbfile);
goto getraw; goto getraw;
} }
exif_get(thumbfile,exifkey,exifdata,1); meta_get1(thumbfile,metakey,metadata,1);
// get thumb image rotation status // get thumb image rotation status
if (exifdata[0]) orientation = *exifdata[0]; if (metadata[0]) orientation = *metadata[0];
else { // no data else { // no data
exif_get(rawfile,exifkey,exifdata,1); meta_get1(rawfile,metakey,metadata,1);
// get raw image rotation status // get raw image rotation status
if (exifdata[0]) orientation = *exifdata[0]; if (metadata[0]) orientation = *metadata[0];
} }
remove(thumbfile); remove(thumbfile);
zfree(thumbfile); zfree(thumbfile);
ww = Tpxb->ww; ww = Tpxb->ww;
hh = Tpxb->hh; hh = Tpxb->hh;
if (ww < 512 && hh < 512) { // embedded image too small if (ww < 512 && hh < 512) { // embedded image too small
PXB_free(Tpxb); PXB_free(Tpxb);
goto getraw; goto getraw;
skipping to change at line 4497 skipping to change at line 4490
Tpxb = PXB_resize(Rpxb,512); // resize to 512 Tpxb = PXB_resize(Rpxb,512); // resize to 512
PXB_free(Rpxb); PXB_free(Rpxb);
return Tpxb; return Tpxb;
} }
// Use the RAW file embedded thumbnail as a template for RAW image color balanc e. // Use the RAW file embedded thumbnail as a template for RAW image color balanc e.
// Input PXM RGB values are revised to match thumbnail histogram. // Input PXM RGB values are revised to match thumbnail histogram.
// returns: 0 = OK, +N = error (PXM not changed). // returns: 0 = OK, +N = error (PXM not changed).
int raw_match_thumb_color(cchar *rawfile, PXM *Rpxm) int raw_match_thumb_color(ch *rawfile, PXM *Rpxm)
{ {
PXB *Tpxb; PXB *Tpxb;
char *thumbfile, *pp; ch *thumbfile, *pp;
int ii, jj, kk, err, rgb, step; int ii, jj, kk, err, rgb, step;
int Tpix, Rpix, Tpix3[3], Rpix3[3]; int Tpix, Rpix, Tpix3[3], Rpix3[3];
int Tdist[3][1024], Rdist[3][1024], Rval[3][1024]; int Tdist[3][1024], Rdist[3][1024], Rval[3][1024];
int Rsum, Tsum, Rbin, Tbin; int Rsum, Tsum, Rbin, Tbin;
uint8 *Tpixel; uint8 *Tpixel;
float *Rpixel; float *Rpixel;
pp = zescape_quotes(rawfile); // get embedded thumbnail file pp = zescape_quotes(rawfile); // get embedded thumbnail file
err = zshell("log","dcraw -e \"%s\" ",pp); // from raw file err = zshell(0,"dcraw -e \"%s\" ",pp); // from raw file
zfree(pp); zfree(pp);
if (err) return 1; if (err) return 1;
thumbfile = zstrdup(rawfile,"raw_match_thumb",12); // rawfile.thumb.jpg thumbfile = zstrdup(rawfile,"raw_match_thumb",12); // rawfile.thumb.jpg
pp = strrchr(thumbfile,'/'); pp = strrchr(thumbfile,'/');
pp = strrchr(pp,'.'); pp = strrchr(pp,'.');
if (! pp) pp = thumbfile + strlen(thumbfile); if (! pp) pp = thumbfile + strlen(thumbfile);
strcpy(pp,".thumb.jpg"); strcpy(pp,".thumb.jpg");
if (regfile(thumbfile)) Tpxb = JPG_PXB_load(thumbfile); // make thumb PXB if (regfile(thumbfile)) Tpxb = JPG_PXB_load(thumbfile); // make thumb PXB
skipping to change at line 4628 skipping to change at line 4621
Rbin = 4 * Rpixel[rgb]; // old brightness Rbin = 4 * Rpixel[rgb]; // old brightness
Rpixel[rgb] = 0.25 * Rval[rgb][Rbin]; // set new brightness Rpixel[rgb] = 0.25 * Rval[rgb][Rbin]; // set new brightness
} }
} }
return 0; return 0;
} }
// PXB version of above. // PXB version of above.
int raw_match_thumb_color(cchar *rawfile, PXB *Rpxb) int raw_match_thumb_color(ch *rawfile, PXB *Rpxb)
{ {
PXB *Tpxb; PXB *Tpxb;
char *thumbfile, *pp; ch *thumbfile, *pp;
int ii, jj, kk, err, rgb, step; int ii, jj, kk, err, rgb, step;
int Tpix, Rpix, Tpix3[3], Rpix3[3]; int Tpix, Rpix, Tpix3[3], Rpix3[3];
int Tdist[3][1024], Rdist[3][1024], Rval[3][1024]; int Tdist[3][1024], Rdist[3][1024], Rval[3][1024];
int Rsum, Tsum, Rbin, Tbin; int Rsum, Tsum, Rbin, Tbin;
uint8 *Tpixel, *Rpixel; uint8 *Tpixel, *Rpixel;
pp = zescape_quotes(rawfile); // get embedded thumbnail file pp = zescape_quotes(rawfile); // get embedded thumbnail file
err = zshell("log","dcraw -e \"%s\" ",pp); // from raw file err = zshell(0,"dcraw -e \"%s\" ",pp); // from raw file
zfree(pp); zfree(pp);
if (err) return 1; if (err) return 1;
thumbfile = zstrdup(rawfile,"raw_match_thumb",12); // rawfile.thumb.jpg thumbfile = zstrdup(rawfile,"raw_match_thumb",12); // rawfile.thumb.jpg
pp = strrchr(thumbfile,'/'); pp = strrchr(thumbfile,'/');
pp = strrchr(pp,'.'); pp = strrchr(pp,'.');
if (! pp) pp = thumbfile + strlen(thumbfile); if (! pp) pp = thumbfile + strlen(thumbfile);
strcpy(pp,".thumb.jpg"); strcpy(pp,".thumb.jpg");
if (regfile(thumbfile)) Tpxb = JPG_PXB_load(thumbfile); // make thumb PXB if (regfile(thumbfile)) Tpxb = JPG_PXB_load(thumbfile); // make thumb PXB
 End of changes. 141 change blocks. 
189 lines changed or deleted 178 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)