template<typename IO, typename Rac, typename Coder> void flif_decode_FLIF2_inner(Rac &rac, std::vector<Coder> &coders, Images &images, const ColorRanges *ranges, const int beginZL, const int endZL, int quality, int scale, std::vector<Transform<IO>*> &transforms, uint32_t (*callback)(int,int), Images &partial_images) { ColorVal min,max; int nump = images[0].numPlanes(); int progressive_qual_target = 0; // if (quality >= 0) { // quality = plane_zoomlevels(image, beginZL, endZL) * quality / 100; // } // flif_decode for (int i = 0; i < plane_zoomlevels(images[0], beginZL, endZL); i++) { std::pair<int, int> pzl = plane_zoomlevel(images[0], beginZL, endZL, i); int p = pzl.first; int z = pzl.second; if ((100*pixels_done > quality*pixels_todo) || 1<<(z/2) < scale) { flif_decode_FLIF2_inner_interpol(images, ranges, i, beginZL, endZL, (z%2 == 0 ?1:0), scale); return; } if (endZL == 0) v_printf(2,"\r%i%% done [%i/%i] DEC[%i,%ux%u] ",(int)(100*pixels_done/pixels_todo),i,plane_zoomlevels(images[0], beginZL, endZL)-1,p,images[0].cols(z),images[0].rows(z)); pixels_done += (images[0].cols(z)/(z%2==0?1:2))*(images[0].rows(z)/(z%2==0?2:1)); if (ranges->min(p) < ranges->max(p)) { ColorVal curr; Properties properties((nump>3?NB_PROPERTIESA[p]:NB_PROPERTIES[p])); if (z % 2 == 0) { for (uint32_t r = 1; r < images[0].rows(z); r += 2) { #ifdef CHECK_FOR_BROKENFILES if (rac.isEOF()) { v_printf(1,"Row %i: Unexpected file end. Interpolation from now on.\n",r); flif_decode_FLIF2_inner_interpol(images, ranges, i, beginZL, endZL, (r>1?r-2:r), scale); return; } #endif for (int fr=0; fr<(int)images.size(); fr++) { Image& image = images[fr]; if (image.seen_before >= 0) { for (uint32_t c=0; c<image.cols(z); c++) image.set(p,z,r,c,images[image.seen_before](p,z,r,c)); continue; } uint32_t begin=image.col_begin[r*image.zoom_rowpixelsize(z)]/image.zoom_colpixelsize(z), end=1+(image.col_end[r*image.zoom_rowpixelsize(z)]-1)/image.zoom_colpixelsize(z); if (fr>0) { for (uint32_t c = 0; c < begin; c++) if (nump>3 && p<3 && image(3,z,r,c) == 0) image.set(p,z,r,c, predict(image,z,p,r,c)); else if (p !=4 ) image.set(p,z,r,c,images[fr-1](p,z,r,c)); /* else if (nump>4 && p<4 && image(4,z,r,c) > 0) image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); else { int oldframe=fr-1; image.set(p,z,r,c,images[oldframe](p,z,r,c)); while(p == 4 && image(p,z,r,c) > 0) {oldframe -= image(p,z,r,c); assert(oldframe>=0); image.set(p,z,r,c,images[oldframe](p,z,r,c));}} */ for (uint32_t c = end; c < image.cols(z); c++) if (nump>3 && p<3 && image(3,z,r,c) == 0) image.set(p,z,r,c, predict(image,z,p,r,c)); else if (p !=4 ) image.set(p,z,r,c,images[fr-1](p,z,r,c)); /* else if (nump>4 && p<4 && image(4,z,r,c) > 0) image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); else { int oldframe=fr-1; image.set(p,z,r,c,images[oldframe](p,z,r,c)); while(p == 4 && image(p,z,r,c) > 0) {oldframe -= image(p,z,r,c); assert(oldframe>=0); image.set(p,z,r,c,images[oldframe](p,z,r,c));}} */ } else { if (nump>3 && p<3) {begin=0; end=image.cols(z);} } for (uint32_t c = begin; c < end; c++) { if (nump>3 && p<3 && image(3,z,r,c) == 0) { image.set(p,z,r,c,predict(image,z,p,r,c)); continue;} if (nump>4 && p<4 && image(4,z,r,c) > 0) { image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); continue;} ColorVal guess = predict_and_calcProps(properties,ranges,image,z,p,r,c,min,max); if (p==4 && max > fr) max = fr; curr = coders[p].read_int(properties, min - guess, max - guess) + guess; image.set(p,z,r,c, curr); } } } } else { for (uint32_t r = 0; r < images[0].rows(z); r++) { #ifdef CHECK_FOR_BROKENFILES if (rac.isEOF()) { v_printf(1,"Row %i: Unexpected file end. Interpolation from now on.\n", r); flif_decode_FLIF2_inner_interpol(images, ranges, i, beginZL, endZL, (r>0?r-1:r), scale); return; } #endif for (int fr=0; fr<(int)images.size(); fr++) { Image& image = images[fr]; if (image.seen_before >= 0) { for (uint32_t c=1; c<image.cols(z); c+=2) image.set(p,z,r,c,images[image.seen_before](p,z,r,c)); continue; } uint32_t begin=(image.col_begin[r*image.zoom_rowpixelsize(z)]/image.zoom_colpixelsize(z)), end=(1+(image.col_end[r*image.zoom_rowpixelsize(z)]-1)/image.zoom_colpixelsize(z))|1; if (begin>1 && ((begin&1) ==0)) begin--; if (begin==0) begin=1; if (fr>0) { for (uint32_t c = 1; c < begin; c+=2) if (nump>3 && p<3 && image(3,z,r,c) == 0) image.set(p,z,r,c, predict(image,z,p,r,c)); else if (p !=4 ) image.set(p,z,r,c,images[fr-1](p,z,r,c)); /* else if (nump>4 && p<4 && image(4,z,r,c) > 0) image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); else { int oldframe=fr-1; image.set(p,z,r,c,images[oldframe](p,z,r,c)); while(p == 4 && image(p,z,r,c) > 0) {oldframe -= image(p,z,r,c); assert(oldframe>=0); image.set(p,z,r,c,images[oldframe](p,z,r,c));}} */ for (uint32_t c = end; c < image.cols(z); c+=2) if (nump>3 && p<3 && image(3,z,r,c) == 0) image.set(p,z,r,c, predict(image,z,p,r,c)); else if (p !=4 ) image.set(p,z,r,c,images[fr-1](p,z,r,c)); /* else if (nump>4 && p<4 && image(4,z,r,c) > 0) image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); else { int oldframe=fr-1; image.set(p,z,r,c,images[oldframe](p,z,r,c)); while(p == 4 && image(p,z,r,c) > 0) {oldframe -= image(p,z,r,c); assert(oldframe>=0); image.set(p,z,r,c,images[oldframe](p,z,r,c));}} */ } else { if (nump>3 && p<3) {begin=1; end=image.cols(z);} } for (uint32_t c = begin; c < end; c+=2) { if (nump>3 && p<3 && image(3,z,r,c) == 0) { image.set(p,z,r,c,predict(image,z,p,r,c)); continue;} if (nump>4 && p<4 && image(4,z,r,c) > 0) { image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); continue;} ColorVal guess = predict_and_calcProps(properties,ranges,image,z,p,r,c,min,max); if (p==4 && max > fr) max = fr; curr = coders[p].read_int(properties, min - guess, max - guess) + guess; image.set(p,z,r,c, curr); } } } } if (endZL==0) { v_printf(3," read %li bytes ", rac.ftell()); v_printf(5,"\n"); } } int qual = 10000*pixels_done/pixels_todo; if (callback && (endZL==0 || i+1 == plane_zoomlevels(images[0], beginZL, endZL)) && qual >= progressive_qual_target) { for (unsigned int n=0; n < images.size(); n++) partial_images[n] = images[n].clone(); // make a copy to work with int64_t pixels_really_done = pixels_done; flif_decode_FLIF2_inner_interpol(partial_images, ranges, i+1, beginZL, endZL, -1, scale); if (endZL>0) flif_decode_FLIF2_inner_interpol(partial_images, ranges, 0, endZL-1, 0, -1, scale); pixels_done = pixels_really_done; for (int i=transforms.size()-1; i>=0; i--) if (transforms[i]->undo_redo_during_decode()) transforms[i]->invData(partial_images); progressive_qual_target = callback(qual,rac.ftell()); if (qual >= progressive_qual_target) break; } } }
template<typename IO, typename Rac, typename Coder> void flif_decode_scanlines_inner(Rac &rac, std::vector<Coder> &coders, Images &images, const ColorRanges *ranges, std::vector<Transform<IO>*> &transforms, uint32_t (*callback)(int,int), Images &partial_images) { ColorVal min,max; int nump = images[0].numPlanes(); int progressive_qual_target = 0; if (callback) { // initialize planes to grey for (int p=0; p<nump; p++) { for (int fr=0; fr< (int)images.size(); fr++) { for (uint32_t r=0; r<images[fr].rows(); r++) { for (uint32_t c=0; c<images[fr].cols(); c++) { images[fr].set(p,r,c,(ranges->min(p)+ranges->max(p))/2); } } } } } for (int k=0,i=0; k < 5; k++) { int p=PLANE_ORDERING[k]; if (p>=nump) continue; i++; Properties properties((nump>3?NB_PROPERTIES_scanlinesA[p]:NB_PROPERTIES_scanlines[p])); v_printf(2,"\r%i%% done [%i/%i] DEC[%ux%u] ",(int)(100*pixels_done/pixels_todo),i,nump,images[0].cols(),images[0].rows()); v_printf(4,"\n"); pixels_done += images[0].cols()*images[0].rows(); if (ranges->min(p) < ranges->max(p)) for (uint32_t r = 0; r < images[0].rows(); r++) { for (int fr=0; fr< (int)images.size(); fr++) { Image& image = images[fr]; uint32_t begin=image.col_begin[r], end=image.col_end[r]; if (image.seen_before >= 0) { for(uint32_t c=0; c<image.cols(); c++) image.set(p,r,c,images[image.seen_before](p,r,c)); continue; } if (fr>0) { for (uint32_t c = 0; c < begin; c++) if (nump>3 && p<3 && image(3,r,c) == 0) image.set(p,r,c,predict(image,p,r,c)); else if (p !=4 ) image.set(p,r,c,images[fr-1](p,r,c)); /* else if (nump>4 && p<4 && image(4,r,c) > 0) image.set(p,r,c,images[fr-image(4,r,c)](p,r,c)); else { int oldframe=fr-1; image.set(p,r,c,images[oldframe](p,r,c)); while(p == 4 && image(p,r,c) > 0) {oldframe -= image(p,r,c); assert(oldframe>=0); image.set(p,r,c,images[oldframe](p,r,c));} } */ } else { if (nump>3 && p<3) { begin=0; end=image.cols(); } } for (uint32_t c = begin; c < end; c++) { if (nump>3 && p<3 && image(3,r,c) == 0) {image.set(p,r,c,predict(image,p,r,c)); continue;} if (nump>4 && p<4 && image(4,r,c) > 0) {assert(fr >= image(4,r,c)); image.set(p,r,c,images[fr-image(4,r,c)](p,r,c)); continue;} ColorVal guess = predict_and_calcProps_scanlines(properties,ranges,image,p,r,c,min,max); if (p==4 && max > fr) max = fr; ColorVal curr = coders[p].read_int(properties, min - guess, max - guess) + guess; image.set(p,r,c, curr); } if (fr>0) { for (uint32_t c = end; c < image.cols(); c++) if (nump>3 && p<3 && image(3,r,c) == 0) image.set(p,r,c,predict(image,p,r,c)); else if (p !=4 ) image.set(p,r,c,images[fr-1](p,r,c)); /* else if (nump>4 && p<4 && image(4,r,c) > 0) image.set(p,r,c,images[fr-image(4,r,c)](p,r,c)); else { int oldframe=fr-1; image.set(p,r,c,images[oldframe](p,r,c)); while(p == 4 && image(p,r,c) > 0) {oldframe -= image(p,r,c); assert(oldframe>=0); image.set(p,r,c,images[oldframe](p,r,c));} }*/ } } } int qual = 10000*pixels_done/pixels_todo; if (callback && qual >= progressive_qual_target) { for (unsigned int n=0; n < images.size(); n++) partial_images[n] = images[n].clone(); // make a copy to work with for (int i=transforms.size()-1; i>=0; i--) if (transforms[i]->undo_redo_during_decode()) transforms[i]->invData(partial_images); progressive_qual_target = callback(qual,rac.ftell()); if (qual >= progressive_qual_target) break; } } }
template<typename Rac, typename Coder> void flif_decode_FLIF2_inner(Rac &rac, std::vector<Coder> &coders, Images &images, const ColorRanges *ranges, const int beginZL, const int endZL, int quality, int scale) { ColorVal min,max; int nump = images[0].numPlanes(); // if (quality >= 0) { // quality = plane_zoomlevels(image, beginZL, endZL) * quality / 100; // } // flif_decode for (int i = 0; i < plane_zoomlevels(images[0], beginZL, endZL); i++) { std::pair<int, int> pzl = plane_zoomlevel(images[0], beginZL, endZL, i); int p = pzl.first; int z = pzl.second; if ((100*pixels_done > quality*pixels_todo) || 1<<(z/2) < scale) { flif_decode_FLIF2_inner_interpol(images, ranges, i, beginZL, endZL, (z%2 == 0 ?1:0), scale); return; } if (endZL == 0) v_printf(2,"\r%i%% done [%i/%i] DEC[%i,%ux%u] ",(int)(100*pixels_done/pixels_todo),i,plane_zoomlevels(images[0], beginZL, endZL)-1,p,images[0].cols(z),images[0].rows(z)); pixels_done += images[0].cols(z)*images[0].rows(z)/2; if (ranges->min(p) >= ranges->max(p)) continue; ColorVal curr; Properties properties((nump>3?NB_PROPERTIESA[p]:NB_PROPERTIES[p])); if (z % 2 == 0) { for (uint32_t r = 1; r < images[0].rows(z); r += 2) { #ifdef CHECK_FOR_BROKENFILES if (rac.isEOF()) { v_printf(1,"Row %i: Unexpected file end. Interpolation from now on.\n",r); flif_decode_FLIF2_inner_interpol(images, ranges, i, beginZL, endZL, (r>1?r-2:r), scale); return; } #endif for (int fr=0; fr<(int)images.size(); fr++) { Image& image = images[fr]; if (image.seen_before >= 0) { for (uint32_t c=0; c<image.cols(z); c++) image.set(p,z,r,c,images[image.seen_before](p,z,r,c)); continue; } uint32_t begin=image.col_begin[r*image.zoom_rowpixelsize(z)]/image.zoom_colpixelsize(z), end=1+(image.col_end[r*image.zoom_rowpixelsize(z)]-1)/image.zoom_colpixelsize(z); if (fr>0) { for (uint32_t c = 0; c < begin; c++) if (nump>3 && p<3 && image(3,z,r,c) == 0) image.set(p,z,r,c, predict(image,z,p,r,c)); else if (p !=4 ) image.set(p,z,r,c,images[fr-1](p,z,r,c)); /* else if (nump>4 && p<4 && image(4,z,r,c) > 0) image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); else { int oldframe=fr-1; image.set(p,z,r,c,images[oldframe](p,z,r,c)); while(p == 4 && image(p,z,r,c) > 0) {oldframe -= image(p,z,r,c); assert(oldframe>=0); image.set(p,z,r,c,images[oldframe](p,z,r,c));}} */ for (uint32_t c = end; c < image.cols(z); c++) if (nump>3 && p<3 && image(3,z,r,c) == 0) image.set(p,z,r,c, predict(image,z,p,r,c)); else if (p !=4 ) image.set(p,z,r,c,images[fr-1](p,z,r,c)); /* else if (nump>4 && p<4 && image(4,z,r,c) > 0) image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); else { int oldframe=fr-1; image.set(p,z,r,c,images[oldframe](p,z,r,c)); while(p == 4 && image(p,z,r,c) > 0) {oldframe -= image(p,z,r,c); assert(oldframe>=0); image.set(p,z,r,c,images[oldframe](p,z,r,c));}} */ } else { if (nump>3 && p<3) {begin=0; end=image.cols(z);} } for (uint32_t c = begin; c < end; c++) { if (nump>3 && p<3 && image(3,z,r,c) == 0) { image.set(p,z,r,c,predict(image,z,p,r,c)); continue;} if (nump>4 && p<4 && image(4,z,r,c) > 0) { image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); continue;} ColorVal guess = predict_and_calcProps(properties,ranges,image,z,p,r,c,min,max); if (p==4 && max > fr) max = fr; curr = coders[p].read_int(properties, min - guess, max - guess) + guess; image.set(p,z,r,c, curr); } } } } else { for (uint32_t r = 0; r < images[0].rows(z); r++) { #ifdef CHECK_FOR_BROKENFILES if (rac.isEOF()) { v_printf(1,"Row %i: Unexpected file end. Interpolation from now on.\n", r); flif_decode_FLIF2_inner_interpol(images, ranges, i, beginZL, endZL, (r>0?r-1:r), scale); return; } #endif for (int fr=0; fr<(int)images.size(); fr++) { Image& image = images[fr]; if (image.seen_before >= 0) { for (uint32_t c=1; c<image.cols(z); c+=2) image.set(p,z,r,c,images[image.seen_before](p,z,r,c)); continue; } uint32_t begin=(image.col_begin[r*image.zoom_rowpixelsize(z)]/image.zoom_colpixelsize(z)), end=(1+(image.col_end[r*image.zoom_rowpixelsize(z)]-1)/image.zoom_colpixelsize(z))|1; if (begin>1 && ((begin&1) ==0)) begin--; if (begin==0) begin=1; if (fr>0) { for (uint32_t c = 1; c < begin; c+=2) if (nump>3 && p<3 && image(3,z,r,c) == 0) image.set(p,z,r,c, predict(image,z,p,r,c)); else if (p !=4 ) image.set(p,z,r,c,images[fr-1](p,z,r,c)); /* else if (nump>4 && p<4 && image(4,z,r,c) > 0) image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); else { int oldframe=fr-1; image.set(p,z,r,c,images[oldframe](p,z,r,c)); while(p == 4 && image(p,z,r,c) > 0) {oldframe -= image(p,z,r,c); assert(oldframe>=0); image.set(p,z,r,c,images[oldframe](p,z,r,c));}} */ for (uint32_t c = end; c < image.cols(z); c+=2) if (nump>3 && p<3 && image(3,z,r,c) == 0) image.set(p,z,r,c, predict(image,z,p,r,c)); else if (p !=4 ) image.set(p,z,r,c,images[fr-1](p,z,r,c)); /* else if (nump>4 && p<4 && image(4,z,r,c) > 0) image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); else { int oldframe=fr-1; image.set(p,z,r,c,images[oldframe](p,z,r,c)); while(p == 4 && image(p,z,r,c) > 0) {oldframe -= image(p,z,r,c); assert(oldframe>=0); image.set(p,z,r,c,images[oldframe](p,z,r,c));}} */ } else { if (nump>3 && p<3) {begin=1; end=image.cols(z);} } for (uint32_t c = begin; c < end; c+=2) { if (nump>3 && p<3 && image(3,z,r,c) == 0) { image.set(p,z,r,c,predict(image,z,p,r,c)); continue;} if (nump>4 && p<4 && image(4,z,r,c) > 0) { image.set(p,z,r,c,images[fr-image(4,z,r,c)](p,z,r,c)); continue;} ColorVal guess = predict_and_calcProps(properties,ranges,image,z,p,r,c,min,max); if (p==4 && max > fr) max = fr; curr = coders[p].read_int(properties, min - guess, max - guess) + guess; image.set(p,z,r,c, curr); } } } } if (endZL==0) { v_printf(3," read %li bytes ", rac.ftell()); v_printf(5,"\n"); } } }