summaryrefslogtreecommitdiff
path: root/libopie2
Unidiff
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opieui/oimageeffect.cpp76
1 files changed, 25 insertions, 51 deletions
diff --git a/libopie2/opieui/oimageeffect.cpp b/libopie2/opieui/oimageeffect.cpp
index 3c28bbe..2855da6 100644
--- a/libopie2/opieui/oimageeffect.cpp
+++ b/libopie2/opieui/oimageeffect.cpp
@@ -55,27 +55,25 @@ inline unsigned int intensityValue(unsigned int color)
55// 55//
56//====================================================================== 56//======================================================================
57 57
58QImage OImageEffect::gradient(const QSize &size, const QColor &ca, 58QImage OImageEffect::gradient(const QSize &size, const QColor &ca,
59 const QColor &cb, GradientType eff, int ncols) 59 const QColor &cb, GradientType eff, int ncols)
60{ 60{
61 int rDiff, gDiff, bDiff; 61 int rDiff, gDiff, bDiff;
62 int rca, gca, bca, rcb, gcb, bcb; 62 int rca, gca, bca, rcb, gcb, bcb;
63 63
64 QImage image(size, 32); 64 QImage image(size, 32);
65 65
66 if (size.width() == 0 || size.height() == 0) { 66 if (size.width() == 0 || size.height() == 0) {
67#ifndef NDEBUG 67 qDebug( "WARNING: OImageEffect::gradient: invalid image" );
68 cerr << "WARNING: OImageEffect::gradient: invalid image" << endl;
69#endif
70 return image; 68 return image;
71 } 69 }
72 70
73 register int x, y; 71 register int x, y;
74 72
75 rDiff = (rcb = cb.red()) - (rca = ca.red()); 73 rDiff = (rcb = cb.red()) - (rca = ca.red());
76 gDiff = (gcb = cb.green()) - (gca = ca.green()); 74 gDiff = (gcb = cb.green()) - (gca = ca.green());
77 bDiff = (bcb = cb.blue()) - (bca = ca.blue()); 75 bDiff = (bcb = cb.blue()) - (bca = ca.blue());
78 76
79 if( eff == VerticalGradient || eff == HorizontalGradient ){ 77 if( eff == VerticalGradient || eff == HorizontalGradient ){
80 78
81 uint *p; 79 uint *p;
@@ -343,27 +341,25 @@ QImage OImageEffect::unbalancedGradient(const QSize &size, const QColor &ca,
343 // float xbal = xfactor/5000.; 341 // float xbal = xfactor/5000.;
344 // float ybal = yfactor/5000.; 342 // float ybal = yfactor/5000.;
345 float xbal = xfactor/30./size.width(); 343 float xbal = xfactor/30./size.width();
346 float ybal = yfactor/30./size.height(); 344 float ybal = yfactor/30./size.height();
347 float rat; 345 float rat;
348 346
349 int rDiff, gDiff, bDiff; 347 int rDiff, gDiff, bDiff;
350 int rca, gca, bca, rcb, gcb, bcb; 348 int rca, gca, bca, rcb, gcb, bcb;
351 349
352 QImage image(size, 32); 350 QImage image(size, 32);
353 351
354 if (size.width() == 0 || size.height() == 0) { 352 if (size.width() == 0 || size.height() == 0) {
355#ifndef NDEBUG 353 qDebug( "WARNING: OImageEffect::unbalancedGradient : invalid image" );
356 cerr << "WARNING: OImageEffect::unbalancedGradient : invalid image\n";
357#endif
358 return image; 354 return image;
359 } 355 }
360 356
361 register int x, y; 357 register int x, y;
362 unsigned int *scanline; 358 unsigned int *scanline;
363 359
364 rDiff = (rcb = cb.red()) - (rca = ca.red()); 360 rDiff = (rcb = cb.red()) - (rca = ca.red());
365 gDiff = (gcb = cb.green()) - (gca = ca.green()); 361 gDiff = (gcb = cb.green()) - (gca = ca.green());
366 bDiff = (bcb = cb.blue()) - (bca = ca.blue()); 362 bDiff = (bcb = cb.blue()) - (bca = ca.blue());
367 363
368 if( eff == VerticalGradient || eff == HorizontalGradient){ 364 if( eff == VerticalGradient || eff == HorizontalGradient){
369 QColor cRow; 365 QColor cRow;
@@ -564,27 +560,25 @@ QImage OImageEffect::unbalancedGradient(const QSize &size, const QColor &ca,
564 560
565 561
566/* This builds a 256 byte unsigned char lookup table with all 562/* This builds a 256 byte unsigned char lookup table with all
567 * the possible percent values prior to applying the effect, then uses 563 * the possible percent values prior to applying the effect, then uses
568 * integer math for the pixels. For any image larger than 9x9 this will be 564 * integer math for the pixels. For any image larger than 9x9 this will be
569 * less expensive than doing a float operation on the 3 color components of 565 * less expensive than doing a float operation on the 3 color components of
570 * each pixel. (mosfet) 566 * each pixel. (mosfet)
571 */ 567 */
572 568
573QImage& OImageEffect::intensity(QImage &image, float percent) 569QImage& OImageEffect::intensity(QImage &image, float percent)
574{ 570{
575 if (image.width() == 0 || image.height() == 0) { 571 if (image.width() == 0 || image.height() == 0) {
576#ifndef NDEBUG 572 qDebug( "WARNING: OImageEffect::intensity : invalid image" );
577 cerr << "WARNING: OImageEffect::intensity : invalid image\n";
578#endif
579 return image; 573 return image;
580 } 574 }
581 575
582 int segColors = image.depth() > 8 ? 256 : image.numColors(); 576 int segColors = image.depth() > 8 ? 256 : image.numColors();
583 unsigned char *segTbl = new unsigned char[segColors]; 577 unsigned char *segTbl = new unsigned char[segColors];
584 int pixels = image.depth() > 8 ? image.width()*image.height() : 578 int pixels = image.depth() > 8 ? image.width()*image.height() :
585 image.numColors(); 579 image.numColors();
586 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : 580 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() :
587 (unsigned int *)image.colorTable(); 581 (unsigned int *)image.colorTable();
588 582
589 bool brighten = (percent >= 0); 583 bool brighten = (percent >= 0);
590 if(percent < 0) 584 if(percent < 0)
@@ -631,27 +625,25 @@ QImage& OImageEffect::intensity(QImage &image, float percent)
631 data[i] = qRgba(r, g, b, a); 625 data[i] = qRgba(r, g, b, a);
632 } 626 }
633 } 627 }
634 delete [] segTbl; 628 delete [] segTbl;
635 629
636 return image; 630 return image;
637} 631}
638 632
639QImage& OImageEffect::channelIntensity(QImage &image, float percent, 633QImage& OImageEffect::channelIntensity(QImage &image, float percent,
640 RGBComponent channel) 634 RGBComponent channel)
641{ 635{
642 if (image.width() == 0 || image.height() == 0) { 636 if (image.width() == 0 || image.height() == 0) {
643#ifndef NDEBUG 637 qDebug( "WARNING: OImageEffect::channelIntensity : invalid image" );
644 cerr << "WARNING: OImageEffect::channelIntensity : invalid image\n";
645#endif
646 return image; 638 return image;
647 } 639 }
648 640
649 int segColors = image.depth() > 8 ? 256 : image.numColors(); 641 int segColors = image.depth() > 8 ? 256 : image.numColors();
650 unsigned char *segTbl = new unsigned char[segColors]; 642 unsigned char *segTbl = new unsigned char[segColors];
651 int pixels = image.depth() > 8 ? image.width()*image.height() : 643 int pixels = image.depth() > 8 ? image.width()*image.height() :
652 image.numColors(); 644 image.numColors();
653 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : 645 unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() :
654 (unsigned int *)image.colorTable(); 646 (unsigned int *)image.colorTable();
655 bool brighten = (percent >= 0); 647 bool brighten = (percent >= 0);
656 if(percent < 0) 648 if(percent < 0)
657 percent = -percent; 649 percent = -percent;
@@ -723,28 +715,26 @@ QImage& OImageEffect::channelIntensity(QImage &image, float percent,
723 delete [] segTbl; 715 delete [] segTbl;
724 716
725 return image; 717 return image;
726} 718}
727 719
728// Modulate an image with an RBG channel of another image 720// Modulate an image with an RBG channel of another image
729// 721//
730QImage& OImageEffect::modulate(QImage &image, QImage &modImage, bool reverse, 722QImage& OImageEffect::modulate(QImage &image, QImage &modImage, bool reverse,
731 ModulationType type, int factor, RGBComponent channel) 723 ModulationType type, int factor, RGBComponent channel)
732{ 724{
733 if (image.width() == 0 || image.height() == 0 || 725 if (image.width() == 0 || image.height() == 0 ||
734 modImage.width() == 0 || modImage.height() == 0) { 726 modImage.width() == 0 || modImage.height() == 0) {
735#ifndef NDEBUG 727 qDebug( "WARNING: OImageEffect::modulate : invalid image" );
736 cerr << "WARNING: OImageEffect::modulate : invalid image\n"; 728 return image;
737#endif
738 return image;
739 } 729 }
740 730
741 int r, g, b, h, s, v, a; 731 int r, g, b, h, s, v, a;
742 QColor clr; 732 QColor clr;
743 int mod=0; 733 int mod=0;
744 unsigned int x1, x2, y1, y2; 734 unsigned int x1, x2, y1, y2;
745 register int x, y; 735 register int x, y;
746 736
747 // for image, we handle only depth 32 737 // for image, we handle only depth 32
748 if (image.depth()<32) image = image.convertDepth(32); 738 if (image.depth()<32) image = image.convertDepth(32);
749 739
750 // for modImage, we handle depth 8 and 32 740 // for modImage, we handle depth 8 and 32
@@ -851,36 +841,34 @@ QImage& OImageEffect::modulate(QImage &image, QImage &modImage, bool reverse,
851 841
852//====================================================================== 842//======================================================================
853// 843//
854// Blend effects 844// Blend effects
855// 845//
856//====================================================================== 846//======================================================================
857 847
858 848
859// Nice and fast direct pixel manipulation 849// Nice and fast direct pixel manipulation
860QImage& OImageEffect::blend(const QColor& clr, QImage& dst, float opacity) 850QImage& OImageEffect::blend(const QColor& clr, QImage& dst, float opacity)
861{ 851{
862 if (dst.width() <= 0 || dst.height() <= 0) 852 if (dst.width() <= 0 || dst.height() <= 0)
863 return dst; 853 return dst;
864 854
865 if (opacity < 0.0 || opacity > 1.0) { 855 if (opacity < 0.0 || opacity > 1.0) {
866#ifndef NDEBUG 856 qDebug( "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1] ");
867 cerr << "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1]\n"; 857 return dst;
868#endif
869 return dst;
870 } 858 }
871 859
872 int depth = dst.depth(); 860 int depth = dst.depth();
873 if (depth != 32) 861 if (depth != 32)
874 dst = dst.convertDepth(32); 862 dst = dst.convertDepth(32);
875 863
876 int pixels = dst.width() * dst.height(); 864 int pixels = dst.width() * dst.height();
877 int rcol, gcol, bcol; 865 int rcol, gcol, bcol;
878 clr.rgb(&rcol, &gcol, &bcol); 866 clr.rgb(&rcol, &gcol, &bcol);
879 867
880#ifdef WORDS_BIGENDIAN // ARGB (skip alpha) 868#ifdef WORDS_BIGENDIAN // ARGB (skip alpha)
881 register unsigned char *data = (unsigned char *)dst.bits() + 1; 869 register unsigned char *data = (unsigned char *)dst.bits() + 1;
882#else // BGRA 870#else // BGRA
883 register unsigned char *data = (unsigned char *)dst.bits(); 871 register unsigned char *data = (unsigned char *)dst.bits();
884#endif 872#endif
885 873
886 for (register int i=0; i<pixels; i++) 874 for (register int i=0; i<pixels; i++)
@@ -894,40 +882,36 @@ QImage& OImageEffect::blend(const QColor& clr, QImage& dst, float opacity)
894 *(data++) += (unsigned char)((gcol - *data) * opacity); 882 *(data++) += (unsigned char)((gcol - *data) * opacity);
895 *(data++) += (unsigned char)((rcol - *data) * opacity); 883 *(data++) += (unsigned char)((rcol - *data) * opacity);
896#endif 884#endif
897 data++; // skip alpha 885 data++; // skip alpha
898 } 886 }
899 return dst; 887 return dst;
900} 888}
901 889
902// Nice and fast direct pixel manipulation 890// Nice and fast direct pixel manipulation
903QImage& OImageEffect::blend(QImage& src, QImage& dst, float opacity) 891QImage& OImageEffect::blend(QImage& src, QImage& dst, float opacity)
904{ 892{
905 if (src.width() <= 0 || src.height() <= 0) 893 if (src.width() <= 0 || src.height() <= 0)
906 return dst; 894 return dst;
907 if (dst.width() <= 0 || dst.height() <= 0) 895 if (dst.width() <= 0 || dst.height() <= 0)
908 return dst; 896 return dst;
909 897
910 if (src.width() != dst.width() || src.height() != dst.height()) { 898 if (src.width() != dst.width() || src.height() != dst.height()) {
911#ifndef NDEBUG 899 qDebug( "WARNING: OImageEffect::blend : src and destination images are not the same size" );
912 cerr << "WARNING: OImageEffect::blend : src and destination images are not the same size\n"; 900 return dst;
913#endif
914 return dst;
915 } 901 }
916 902
917 if (opacity < 0.0 || opacity > 1.0) { 903 if (opacity < 0.0 || opacity > 1.0) {
918#ifndef NDEBUG 904 qDebug( "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1]" );
919 cerr << "WARNING: OImageEffect::blend : invalid opacity. Range [0, 1]\n"; 905 return dst;
920#endif
921 return dst;
922 } 906 }
923 907
924 if (src.depth() != 32) src = src.convertDepth(32); 908 if (src.depth() != 32) src = src.convertDepth(32);
925 if (dst.depth() != 32) dst = dst.convertDepth(32); 909 if (dst.depth() != 32) dst = dst.convertDepth(32);
926 910
927 int pixels = src.width() * src.height(); 911 int pixels = src.width() * src.height();
928#ifdef WORDS_BIGENDIAN // ARGB (skip alpha) 912#ifdef WORDS_BIGENDIAN // ARGB (skip alpha)
929 register unsigned char *data1 = (unsigned char *)dst.bits() + 1; 913 register unsigned char *data1 = (unsigned char *)dst.bits() + 1;
930 register unsigned char *data2 = (unsigned char *)src.bits() + 1; 914 register unsigned char *data2 = (unsigned char *)src.bits() + 1;
931#else // BGRA 915#else // BGRA
932 register unsigned char *data1 = (unsigned char *)dst.bits(); 916 register unsigned char *data1 = (unsigned char *)dst.bits();
933 register unsigned char *data2 = (unsigned char *)src.bits(); 917 register unsigned char *data2 = (unsigned char *)src.bits();
@@ -948,28 +932,26 @@ QImage& OImageEffect::blend(QImage& src, QImage& dst, float opacity)
948 data2++; 932 data2++;
949 } 933 }
950 934
951 return dst; 935 return dst;
952} 936}
953 937
954 938
955QImage& OImageEffect::blend(QImage &image, float initial_intensity, 939QImage& OImageEffect::blend(QImage &image, float initial_intensity,
956 const QColor &bgnd, GradientType eff, 940 const QColor &bgnd, GradientType eff,
957 bool anti_dir) 941 bool anti_dir)
958{ 942{
959 if (image.width() == 0 || image.height() == 0 || image.depth()!=32 ) { 943 if (image.width() == 0 || image.height() == 0 || image.depth()!=32 ) {
960#ifndef NDEBUG 944 qDebug( "WARNING: OImageEffect::blend : invalid image" );
961 cerr << "WARNING: OImageEffect::blend : invalid image\n"; 945 return image;
962#endif
963 return image;
964 } 946 }
965 947
966 int r_bgnd = bgnd.red(), g_bgnd = bgnd.green(), b_bgnd = bgnd.blue(); 948 int r_bgnd = bgnd.red(), g_bgnd = bgnd.green(), b_bgnd = bgnd.blue();
967 int r, g, b; 949 int r, g, b;
968 int ind; 950 int ind;
969 951
970 unsigned int xi, xf, yi, yf; 952 unsigned int xi, xf, yi, yf;
971 unsigned int a; 953 unsigned int a;
972 954
973 // check the boundaries of the initial intesity param 955 // check the boundaries of the initial intesity param
974 float unaffected = 1; 956 float unaffected = 1;
975 if (initial_intensity > 1) initial_intensity = 1; 957 if (initial_intensity > 1) initial_intensity = 1;
@@ -1143,27 +1125,25 @@ QImage& OImageEffect::blend(QImage &image, float initial_intensity,
1143 g = qGreen(data[ind]) + (int)(intensity * 1125 g = qGreen(data[ind]) + (int)(intensity *
1144 (g_bgnd - qGreen(data[ind]))); 1126 (g_bgnd - qGreen(data[ind])));
1145 b = qBlue (data[ind]) + (int)(intensity * 1127 b = qBlue (data[ind]) + (int)(intensity *
1146 (b_bgnd - qBlue (data[ind]))); 1128 (b_bgnd - qBlue (data[ind])));
1147 if (r > 255) r = 255; if (r < 0 ) r = 0; 1129 if (r > 255) r = 255; if (r < 0 ) r = 0;
1148 if (g > 255) g = 255; if (g < 0 ) g = 0; 1130 if (g > 255) g = 255; if (g < 0 ) g = 0;
1149 if (b > 255) b = 255; if (b < 0 ) b = 0; 1131 if (b > 255) b = 255; if (b < 0 ) b = 0;
1150 a = qAlpha(data[ind]); 1132 a = qAlpha(data[ind]);
1151 data[ind] = qRgba(r, g, b, a); 1133 data[ind] = qRgba(r, g, b, a);
1152 } 1134 }
1153 } 1135 }
1154 } 1136 }
1155#ifndef NDEBUG 1137 else qDebug( "OImageEffect::blend effect not implemented" );
1156 else cerr << "OImageEffect::blend effect not implemented" << endl;
1157#endif
1158 return image; 1138 return image;
1159} 1139}
1160 1140
1161// Not very efficient as we create a third big image... 1141// Not very efficient as we create a third big image...
1162// 1142//
1163QImage& OImageEffect::blend(QImage &image1, QImage &image2, 1143QImage& OImageEffect::blend(QImage &image1, QImage &image2,
1164 GradientType gt, int xf, int yf) 1144 GradientType gt, int xf, int yf)
1165{ 1145{
1166 if (image1.width() == 0 || image1.height() == 0 || 1146 if (image1.width() == 0 || image1.height() == 0 ||
1167 image2.width() == 0 || image2.height() == 0) 1147 image2.width() == 0 || image2.height() == 0)
1168 return image1; 1148 return image1;
1169 1149
@@ -1175,28 +1155,26 @@ QImage& OImageEffect::blend(QImage &image1, QImage &image2,
1175 1155
1176 return blend(image1,image2,image3, Red); // Channel to use is arbitrary 1156 return blend(image1,image2,image3, Red); // Channel to use is arbitrary
1177} 1157}
1178 1158
1179// Blend image2 into image1, using an RBG channel of blendImage 1159// Blend image2 into image1, using an RBG channel of blendImage
1180// 1160//
1181QImage& OImageEffect::blend(QImage &image1, QImage &image2, 1161QImage& OImageEffect::blend(QImage &image1, QImage &image2,
1182 QImage &blendImage, RGBComponent channel) 1162 QImage &blendImage, RGBComponent channel)
1183{ 1163{
1184 if (image1.width() == 0 || image1.height() == 0 || 1164 if (image1.width() == 0 || image1.height() == 0 ||
1185 image2.width() == 0 || image2.height() == 0 || 1165 image2.width() == 0 || image2.height() == 0 ||
1186 blendImage.width() == 0 || blendImage.height() == 0) { 1166 blendImage.width() == 0 || blendImage.height() == 0) {
1187#ifndef NDEBUG 1167 qDebug( "OImageEffect::blend effect invalid image" );
1188 cerr << "OImageEffect::blend effect invalid image" << endl; 1168 return image1;
1189#endif
1190 return image1;
1191 } 1169 }
1192 1170
1193 int r, g, b; 1171 int r, g, b;
1194 int ind1, ind2, ind3; 1172 int ind1, ind2, ind3;
1195 1173
1196 unsigned int x1, x2, x3, y1, y2, y3; 1174 unsigned int x1, x2, x3, y1, y2, y3;
1197 unsigned int a; 1175 unsigned int a;
1198 1176
1199 register int x, y; 1177 register int x, y;
1200 1178
1201 // for image1 and image2, we only handle depth 32 1179 // for image1 and image2, we only handle depth 32
1202 if (image1.depth()<32) image1 = image1.convertDepth(32); 1180 if (image1.depth()<32) image1 = image1.convertDepth(32);
@@ -1275,28 +1253,26 @@ unsigned int OImageEffect::uHash(unsigned int c)
1275 ng = g + (g >> 3); ng = ng < g ? ~0 : ng; 1253 ng = g + (g >> 3); ng = ng < g ? ~0 : ng;
1276 nb = b + (b >> 3); nb = nb < b ? ~0 : nb; 1254 nb = b + (b >> 3); nb = nb < b ? ~0 : nb;
1277 1255
1278 return qRgba(nr, ng, nb, a); 1256 return qRgba(nr, ng, nb, a);
1279} 1257}
1280 1258
1281 1259
1282// ----------------------------------------------------------------------------- 1260// -----------------------------------------------------------------------------
1283 1261
1284QImage& OImageEffect::hash(QImage &image, Lighting lite, unsigned int spacing) 1262QImage& OImageEffect::hash(QImage &image, Lighting lite, unsigned int spacing)
1285{ 1263{
1286 if (image.width() == 0 || image.height() == 0) { 1264 if (image.width() == 0 || image.height() == 0) {
1287#ifndef NDEBUG 1265 qDebug( "OImageEffect::hash effect invalid image" );
1288 cerr << "OImageEffect::hash effect invalid image" << endl; 1266 return image;
1289#endif
1290 return image;
1291 } 1267 }
1292 1268
1293 register int x, y; 1269 register int x, y;
1294 unsigned int *data = (unsigned int *)image.bits(); 1270 unsigned int *data = (unsigned int *)image.bits();
1295 unsigned int ind; 1271 unsigned int ind;
1296 1272
1297 //CT no need to do it if not enough space 1273 //CT no need to do it if not enough space
1298 if ((lite == NorthLite || 1274 if ((lite == NorthLite ||
1299 lite == SouthLite)&& 1275 lite == SouthLite)&&
1300 (unsigned)image.height() < 2+spacing) return image; 1276 (unsigned)image.height() < 2+spacing) return image;
1301 if ((lite == EastLite || 1277 if ((lite == EastLite ||
1302 lite == WestLite)&& 1278 lite == WestLite)&&
@@ -1785,28 +1761,26 @@ bool OImageEffect::blend(
1785 const QImage & upper, 1761 const QImage & upper,
1786 const QImage & lower, 1762 const QImage & lower,
1787 QImage & output 1763 QImage & output
1788) 1764)
1789{ 1765{
1790 if ( 1766 if (
1791 upper.width() > lower.width() || 1767 upper.width() > lower.width() ||
1792 upper.height() > lower.height() || 1768 upper.height() > lower.height() ||
1793 upper.depth() != 32 || 1769 upper.depth() != 32 ||
1794 lower.depth() != 32 1770 lower.depth() != 32
1795 ) 1771 )
1796 { 1772 {
1797#ifndef NDEBUG 1773 qDebug( "OImageEffect::blend : Sizes not correct" );
1798 cerr << "OImageEffect::blend : Sizes not correct\n" ; 1774 return false;
1799#endif
1800 return false;
1801 } 1775 }
1802 1776
1803 output = lower.copy(); 1777 output = lower.copy();
1804 1778
1805 register uchar *i, *o; 1779 register uchar *i, *o;
1806 register int a; 1780 register int a;
1807 register int col; 1781 register int col;
1808 register int w = upper.width(); 1782 register int w = upper.width();
1809 int row(upper.height() - 1); 1783 int row(upper.height() - 1);
1810 1784
1811 do { 1785 do {
1812 1786