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 |