
استغلال إثبات المفهوم لثغرة CVE-2023-1999 التي تستهدف مكتبة WebP codec على نظام Android 10 (r33). يُظهر ثغرة تجاوز سعة المخزن المؤقت في الكومة (heap buffer overflow) في مكتبة libwebp، مما يتيح تنفيذ تعليمات برمجية عن بُعد عبر صورة WebP مُصنّعة.
/ \\/ \/ _ \/ _ )/ _ \
\ / __/ _ \ __/
\__\__/\____/\_____/__/ ____ ___
/ _/ / \ \ / _ \/ _/
/ \_/ / / \ \ __/ \__
\____/____/\_____/_____/____/v1.0.2
برنامج ترميز WebP: مكتبة لتشفير وفك تشفير الصور بتنسيق WebP. تحتوي هذه الحزمة على المكتبة التي يمكن استخدامها في برامج أخرى لإضافة دعم WebP، بالإضافة إلى أدوات سطر الأوامر 'cwebp' و 'dwebp'.
انظر http://developers.google.com/speed/webp
شجرة المصدر الأحدث متوفرة على https://chromium.googlesource.com/webm/libwebp
تم إصدارها بموجب نفس ترخيص مشروع WebM. انظر http://www.webmproject.org/license/software/ أو ملف "COPYING" للحصول على التفاصيل. يمكن العثور على منحة إضافية لحقوق الملكية الفكرية في ملف PATENTS.
عن طريق تشغيل:
nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
سيحتوي الدليل output\release-static(x64|x86)\bin على الأدوات cwebp.exe و dwebp.exe. سيحتوي الدليل output\release-static(x64|x86)\lib على مكتبة libwebp الثابتة. يتم اكتشاف البنية المستهدفة (x86/x64) بواسطة Makefile.vc من مترجم Visual Studio (cl.exe) المتاح في مسار النظام.
على الأنظمة الأساسية المثبت عليها أدوات GNU (gcc و make)، يؤدي تشغيل
make -f makefile.unix
إلى بناء الثنائيات examples/cwebp و examples/dwebp، بالإضافة إلى المكتبة الثابتة src/libwebp.a. لا يتم توفير تثبيت على مستوى النظام، حيث أن هذا بديل بسيط لنظام التثبيت الكامل القائم على أدوات autoconf (انظر أدناه). يرجى الرجوع إلى makefile.unix للحصول على تفاصيل إضافية وتخصيصات.
المتطلبات الأساسية: مترجم (مثل gcc)، make، autoconf، automake، libtool. على نظام يشبه Debian، يجب أن يقوم ما يلي بتثبيت كل ما تحتاجه لبناء أساسي: $ sudo apt-get install gcc make autoconf automake libtool
عند البناء من مصادر git، ستحتاج إلى تشغيل autogen.sh لإنشاء نص التهيئة.
./configure make make install
يجب أن يكون كل ما تحتاجه للحصول على الملفات التالية
/usr/local/include/webp/decode.h /usr/local/include/webp/encode.h /usr/local/include/webp/types.h /usr/local/lib/libwebp.* /usr/local/bin/cwebp /usr/local/bin/dwebp
مثبتة.
ملاحظة: مكتبة فك التشفير فقط، libwebpdecoder، متوفرة باستخدام العلم '--enable-libwebpdecoder'. يتم بناء مكتبة التشفير بشكل منفصل ويمكن تثبيتها بشكل مستقل باستخدام تعديل بسيط في ملفات Makefile.am configure المقابلة (انظر التعليقات هناك). انظر './configure --help' لمزيد من الخيارات.
يمكن العثور على إصدارات مستقرة من سلسلة أدوات MIPS Linux على: https://community.imgtec.com/developers/mips/tools/codescape-mips-sdk/available-releases/
export PATH=$PATH:/path/to/toolchain/bin
HOST=mips-mti-linux-gnu
MIPS_CFLAGS="-O3 -mips32r5 -mabi=32 -mtune=p5600 -mmsa -mfp64
-msched-weight -mload-store-pairs -fPIE"
MIPS_LDFLAGS="-mips32r5 -mabi=32 -mmsa -mfp64 -pie"
HOST=mips-img-linux-gnu
MIPS_CFLAGS="-O3 -mips64r6 -mabi=64 -mtune=i6400 -mmsa -mfp64
-msched-weight -mload-store-pairs -fPIE"
MIPS_LDFLAGS="-mips64r6 -mabi=64 -mmsa -mfp64 -pie"
./configure --host=${HOST} --build=config.guess
CC="${HOST}-gcc -EL"
CFLAGS="$MIPS_CFLAGS"
LDFLAGS="$MIPS_LDFLAGS"
make
make install
باستخدام CMake، يمكنك تجميع libwebp، cwebp، dwebp، gif2web، img2webp، webpinfo وارتباطات JS.
المتطلبات الأساسية: مترجم (مثل gcc مع autotools) و CMake. على نظام يشبه Debian، يجب أن يقوم ما يلي بتثبيت كل ما تحتاجه لبناء أساسي: $ sudo apt-get install build-essential cmake
عند البناء من مصادر git، ستحتاج إلى تشغيل cmake لإنشاء ملفات make.
mkdir build && cd build && cmake ../ make make install
إذا كنت تريد أيضًا أيًا من البرامج القابلة للتنفيذ، فستحتاج إلى تمكينها من خلال CMake، على سبيل المثال:
cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../
أو من خلال واجهتك المفضلة (مثل ccmake أو cmake-qt-gui).
استخدم الخيار -DWEBP_UNICODE=ON لدعم Unicode على Windows (مع chcp 65001).
أخيرًا، بمجرد التثبيت، يمكنك أيضًا استخدام WebP في مشروع CMake الخاص بك عن طريق:
find_package(WebP)
والذي سيحدد متغيرات CMake WebP_INCLUDE_DIRS و WebP_LIBRARIES.
دعم Gradle ضئيل: يساعدك فقط في تجميع libwebp و cwebp و dwebp و webpmux_example.
المتطلبات الأساسية: مترجم (مثل gcc مع autotools) و gradle. على نظام يشبه Debian، يجب أن يقوم ما يلي بتثبيت كل ما تحتاجه لبناء أساسي: $ sudo apt-get install build-essential gradle
عند البناء من مصادر git، ستحتاج إلى تشغيل Gradle wrapper مع الهدف المناسب، على سبيل المثال:
./gradlew buildAllExecutables
لتوليد ارتباطات اللغة من swig/libwebp.swig، يلزم على الأقل swig-1.3 (http://www.swig.org).
حاليًا، يتم تعيين الوظائف التالية: فك التشفير: WebPGetDecoderVersion WebPGetInfo WebPDecodeRGBA WebPDecodeARGB WebPDecodeBGRA WebPDecodeBGR WebPDecodeRGB
التشفير: WebPGetEncoderVersion WebPEncodeRGBA WebPEncodeBGRA WebPEncodeRGB WebPEncodeBGR WebPEncodeLosslessRGBA WebPEncodeLosslessBGRA WebPEncodeLosslessRGB WebPEncodeLosslessBGR
انظر swig/README للحصول على تعليمات بناء أكثر تفصيلاً.
ارتباطات Java:
لبناء كود غلاف JNI الذي تم إنشاؤه بواسطة swig، يلزم على الأقل JDK-1.5 (أو ما يعادله) لدعم التعداد. الإخراج المقصود هو كائن مشترك / DLL يمكن تحميله عبر System.loadLibrary("webp_jni").
ارتباطات Python:
لبناء كود إضافة Python الذي تم إنشاؤه بواسطة swig، يلزم على الأقل Python 2.6. قد يعمل Python < 2.6 مع بعض التغييرات الطفيفة في libwebp.swig أو الكود المُنشأ، لكنه غير مختبر.
يحتوي دليل examples/ على أدوات للتشفير (cwebp) وفك التشفير (dwebp) للصور.
يجب أن يكون الاستخدام الأسهل على النحو التالي: cwebp input.png -q 80 -o output.webp والذي سيحول ملف الإدخال إلى ملف WebP باستخدام عامل جودة 80 على مقياس 0->100 (0 أدنى جودة، 100 الأفضل. القيمة الافتراضية هي 75). قد ترغب أيضًا في تجربة العلم -lossless، والذي سيضغط المصدر (بتنسيق RGBA) دون أي خسارة. ستتحكم معلمة الجودة -q في هذه الحالة في مقدار وقت المعالجة الذي يتم إنفاقه في محاولة جعل ملف الإخراج صغيرًا قدر الإمكان.
قائمة أطول من الخيارات متاحة باستخدام علم سطر الأوامر -longhelp:
cwebp -longhelp الاستخدام: cwebp [-preset <...>] [options] in_file [-o out_file]
إذا لم يتم تحديد حجم الإدخال (-s) لصورة، فمن المفترض أن يكون ملف PNG أو JPEG أو TIFF أو WebP.
الخيارات: -h / -help ............. مساعدة قصيرة -H / -longhelp ......... مساعدة طويلة -q ............. عامل الجودة (0:صغير..100:كبير)، الافتراضي=75 -alpha_q ......... جودة ضغط الشفافية (0..100)، الافتراضي=100 -preset ........... إعداد مسبق، واحد من: default, photo, picture, drawing, icon, text -preset يجب أن يأتي أولاً، لأنه يلغي المعلمات الأخرى -z ............... ينشط الإعداد المسبق بدون فقدان مع مستوى معين في [0:سريع, ..., 9:أبطأ]
-m ............... طريقة الضغط (0=سريع، 6=أبطأ)، الافتراضي=4 -segments ........ عدد الشرائح المراد استخدامها (1..4)، الافتراضي=4 -size ............ الحجم المستهدف (بالبايت) -psnr .......... PSNR المستهدف (بالديسيبل. عادةً: 42)
-s ......... حجم الإدخال (العرض × الارتفاع) لـ YUV -sns ............. تشكيل الضوضاء المكانية (0:إيقاف، 100:أقصى)، الافتراضي=50 -f ............... قوة المرشح (0=إيقاف..100)، الافتراضي=60 -sharpness ........... حدة المرشح (0:الأكثر .. 7:الأقل حدة)، الافتراضي=0 -strong ................ استخدم مرشحًا قويًا بدلاً من البسيط (الافتراضي) -nostrong .............. استخدم مرشحًا بسيطًا بدلاً من القوي -sharp_yuv ............. استخدم تحويل RGB->YUV أكثر حدة (وأبطأ) -partition_limit . حد الجودة لتناسب حد 512 كيلو بايت على القسم الأول (0=لا تدهور ... 100=كامل) -pass ............ رقم مرور التحليل (1..10) -crop .. قص الصورة بالمستطيل المعطى -resize ........ تغيير حجم الصورة (بعد أي قص) -mt .................... استخدم تعدد المهام إذا كان متاحًا -low_memory ............ تقليل استخدام الذاكرة (تشفير أبطأ) -map ............. طباعة خريطة المعلومات الإضافية -print_psnr ............ يطبع متوسط تشويه PSNR -print_ssim ............ يطبع متوسط تشويه SSIM -print_lsim ............ يطبع تشويه التشابه المحلي -d <file.pgm> .......... تفريغ الإخراج المضغوط (ملف PGM) -alpha_method .... طريقة ضغط الشفافية (0..1)، الافتراضي=1 -alpha_filter . التصفية التنبؤية لمستوى alpha، واحد من: none, fast (الافتراضي) أو best -exact ................. الحفاظ على قيم RGB في المنطقة الشفافة، الافتراضي=إيقاف -blend_alpha ..... مزج الألوان مقابل لون الخلفية معبرًا عنه بقيم RGB مكتوبة بالنظام الست عشري، على سبيل المثال 0xc0e0d0 للأحمر=0xc0 الأخضر=0xe0 والأزرق=0xd0 -noalpha ............... تجاهل أي معلومات شفافية -lossless .............. تشفير الصورة بدون فقدان، الافتراضي=إيقاف -near_lossless ... استخدام معالجة مسبقة للصورة قريبة من عدم الفقدان (0..100=إيقاف)، الافتراضي=100 -hint ......... تحديد تلميح خصائص الصورة، واحد من: photo, picture أو graph
-metadata ..... قائمة مفصولة بفاصلة من البيانات الوصفية المراد نسخها من الإدخال إلى الإخراج إذا كانت موجودة. القيم الصالحة: all, none (الافتراضي), exif, icc, xmp
-short ................. ضغط الرسالة المطبوعة -quiet ................. لا تطبع شيئًا -version ............... طباعة رقم الإصدار والخروج -noasm ................. تعطيل جميع تحسينات التجميع -v ..................... مطول، على سبيل المثال طباعة أوقات التشفير/فك التشفير -progress .............. الإبلاغ عن تقدم التشفير
الخيارات التجريبية: -jpeg_like ............. مطابقة حجم JPEG المتوقع تقريبًا -af .................... ضبط قوة المرشح تلقائيًا -pre ............. مرشح ما قبل المعالجة
الخيارات الرئيسية التي قد ترغب في تجربتها من أجل ضبط الجودة البصرية بشكل أكبر هي: -preset -sns -f -m
وهي:
هناك عينة لفك التشفير في examples/dwebp.c والتي ستأخذ ملف .webp وتفك تشفيره إلى ملف صورة PNG (ضمن تنسيقات أخرى). هذا ببساطة لإظهار استخدام API. يمكنك التحقق من أن ملف test.webp يتم فك تشفيره تمامًا مثل test_ref.ppm باستخدام:
cd examples ./dwebp test.webp -ppm -o test.ppm diff test.ppm test_ref.ppm
القائمة الكاملة للخيارات متاحة باستخدام -h:
dwebp -h الاستخدام: dwebp in_file [options] [-o out_file]
يفك تشفير ملف صورة WebP إلى تنسيق PNG [الافتراضي] استخدم الخيارات التالية للتحويل إلى تنسيقات صور بديلة: -pam ......... حفظ عينات RGBA الأولية كـ PAM ملونة -ppm ......... حفظ عينات RGB الأولية كـ PPM ملونة -bmp ......... حفظ كتنسيق BMP غير مضغوط -tiff ........ حفظ كتنسيق TIFF غير مضغوط -pgm ......... حفظ عينات YUV الأولية كـ PGM بتدرج الرمادي بتخطيط IMC4 -yuv ......... حفظ عينات YUV الأولية بتخطيط مسطح
الخيارات الأخرى هي: -version ..... طباعة رقم الإصدار والخروج -nofancy ..... لا تستخدم مقياس YUV420 الفاخر -nofilter .... تعطيل التصفية داخل الحلقة -nodither .... تعطيل التردد -dither .. قوة التردد (في 0..100) -alpha_dither استخدام تردد مستوى ألفا إذا لزم الأمر -mt .......... استخدم تعدد المهام -crop ... قص الإخراج بالمستطيل المعطى -resize ......... تغيير حجم الإخراج (بعد أي قص) -flip ........ اقلب الإخراج رأسيًا -alpha ....... حفظ مستوى ألفا فقط -incremental . استخدام فك التشفير التدريجي (مفيد للاختبارات) -h ........... رسالة المساعدة هذه -v ........... مطول (على سبيل المثال طباعة أوقات التشفير/فك التشفير) -quiet ....... الوضع الصامت، لا تطبع شيئًا -noasm ....... تعطيل جميع تحسينات التجميع
يمكن استخدام 'webpinfo' لطباعة بنية مستوى القطعة ومعلومات رأس تدفق البت لملفات WebP. يمكنه أيضًا التحقق مما إذا كانت الملفات بتنسيق WebP صالح.
الاستخدام: webpinfo [options] in_files ملاحظة: يمكن أن تكون هناك ملفات إدخال متعددة؛ يجب أن تأتي الخيارات قبل ملفات الإدخال. الخيارات: -version ........... طباعة رقم الإصدار والخروج. -quiet ............. لا تظهر معلومات تحليل القطعة. -diag .............. إظهار تشخيص خطأ التحليل. -summary ........... إظهار ملخص إحصائيات القطعة. -bitstream_info .... تحليل رأس تدفق البت.
هناك أداة تصور صغيرة للخدمة الذاتية تسمى 'vwebp' تحت دليل examples/. تستخدم OpenGL لفتح نافذة رسم بسيطة وإظهار ملف WebP مفكك التشفير. لم يتم دمجها بعد في نظام بناء automake، ولكن يمكنك محاولة تجميعها يدويًا باستخدام التوصيات أدناه.
الاستخدام: vwebp in_file [options]
يفك تشفير ملف صورة WebP ويصورها باستخدام OpenGL الخيارات هي: -version ..... طباعة رقم الإصدار والخروج -noicc ....... لا تستخدم ملف تعريف ICC إذا كان موجودًا -nofancy ..... لا تستخدم مقياس YUV420 الفاخر -nofilter .... تعطيل التصفية داخل الحلقة -dither قوة التردد (0..100)، الافتراضي=50 -noalphadither تعطيل تردد مستوى ألفا -usebgcolor .. عرض لون الخلفية -mt .......... استخدم تعدد المهام -info ........ طباعة المعلومات -h ........... رسالة المساعدة هذه
اختصارات لوحة المفاتيح: 'c' ................ تبديل استخدام ملف تعريف الألوان 'b' ................ تبديل عرض لون الخلفية 'i' ................ تراكب معلومات الملف 'd' ................ تعطيل المزج والتخلص (التصحيح) 'q' / 'Q' / ESC .... الخروج
المتطلبات الأساسية:
OpenGL و OpenGL Utility Toolkit (GLUT) Linux: $ sudo apt-get install freeglut3-dev mesa-common-dev Mac + XCode:
(اختياري) qcms (نظام إدارة الألوان السريع) i. قم بتنزيل qcms من Mozilla / Chromium: http://hg.mozilla.org/mozilla-central/file/0e7639e3bdfb/gfx/qcms http://src.chromium.org/viewvc/chrome/trunk/src/third_party/qcms ii. قم ببناء وأرشفة ملفات المصدر كـ libqcms.a / qcms.lib iii. قم بتحديث makefile.unix / Makefile.vc a) حدد WEBP_HAVE_QCMS b) قم بتحديث مسارات التضمين/المكتبة للإشارة إلى دليل qcms.
البناء باستخدام makefile.unix / Makefile.vc: $ make -f makefile.unix examples/vwebp
nmake /f Makefile.vc CFG=release-static
../obj/x64/release-static/bin/vwebp.exe
يمكن للأداة المساعدة 'img2webp' تحويل سلسلة من صور الإدخال (PNG، JPEG، ...) إلى ملف WebP متحرك. تقدم تحكمًا دقيقًا في المدة، أوضاع التشفير، إلخ.
الاستخدام:
img2webp [file-level options] [image files...] [per-frame options...]
خيارات مستوى الملف (تُستخدم فقط في بداية الضغط): -min_size ............ تصغير الحجم -loop .......... عدد التكرارات (الافتراضي: 0، = تكرار لا نهائي) -kmax .......... الحد الأقصى لعدد الإطارات بين الإطارات الرئيسية (0=الإطارات الرئيسية فقط) -kmin .......... الحد الأدنى لعدد الإطارات بين الإطارات الرئيسية (0=تعطيل الإطارات الرئيسية تمامًا) -mixed ............... استخدام الوضع التلقائي المختلط مع الفقدان/بدون فقدان -v ................... وضع مطول -h ................... هذه المساعدة -version ............. طباعة رقم الإصدار والخروج
خيارات كل إطار (تُستخدم فقط لصور الإدخال اللاحقة): -d ............. مدة الإطار بالمللي ثانية (الافتراضي: 100) -lossless ........... استخدام وضع بدون فقدان (الافتراضي) -lossy ... ........... استخدام وضع مع فقدان -q ........... الجودة -m ............. الطريقة المراد استخدامها
مثال: img2webp -loop 2 in0.png -lossy in1.jpg -d 80 in2.tiff -o out.webp
ملاحظة: إذا تم تمرير اسم ملف واحد كوسيطة، فسيتم تحليل الوسائط من هذا الملف. يجب ألا يبدأ اسم الملف بالحرف '-'.
يمكن تحويل ملفات GIF المتحركة إلى ملفات WebP متحركة باستخدام الأداة المساعدة gif2webp المتوفرة تحت examples/. يمكن بعد ذلك عرض الملفات باستخدام vwebp.
الاستخدام: gif2webp [options] gif_file -o webp_file الخيارات: -h / -help ............. هذه المساعدة -lossy ................. تشفير الصورة باستخدام ضغط مع فقدان -mixed ................. لكل إطار في الصورة، اختر ضغط مع فقدان أو بدون فقدان بشكل إرشادي -q ............. عامل الجودة (0:صغير..100:كبير) -m ............... طريقة الضغط (0=سريع، 6=أبطأ) -min_size .............. تصغير حجم الإخراج (الافتراضي:إيقاف) ضغط بدون فقدان افتراضيًا؛ يمكن دمجه مع خيارات -q و -m و -lossy أو -mixed -kmin ............ الحد الأدنى للمسافة بين الإطارات الرئيسية -kmax ............ الحد الأقصى للمسافة بين الإطارات الرئيسية -f ............... قوة المرشح (0=إيقاف..100) -metadata ..... قائمة مفصولة بفاصلة من البيانات الوصفية المراد نسخها من الإدخال إلى الإخراج إذا كانت موجودة القيم الصالحة: all, none, icc, xmp (الافتراضي) -loop_compatibility .... استخدام وضع التوافق لإصدار Chrome قبل M62 (شاملاً) -mt .................... استخدم تعدد المهام إذا كان متاحًا
-version ............... طباعة رقم الإصدار والخروج -v ..................... مطول -quiet ................. لا تطبع شيئًا
مع تثبيت ملفات تطوير libgif، يمكن بناء gif2webp باستخدام makefile.unix: $ make -f makefile.unix examples/gif2webp
أو باستخدام autoconf: $ ./configure --enable-everything $ make
يمكن استخدام الأداة المساعدة للاختبار anim_diff تحت examples/ لمقارنة صورتين متحركتين (يمكن أن تكون كل منهما GIF أو WebP).الاستخدام: anim_diff [خيارات]
الخيارات: -dump_frames <مجلد> ... تفريغ الإطارات المفكوكة بصيغة PAM -min_psnr <رقم عشري> ... أدنى قيمة PSNR لكل إطار -raw_comparison ..... إذا لم يُستخدم هذا العلم، يتم ضرب RGB مسبقًا قبل المقارنة -max_diff <عدد صحيح> ..... أقصى فرق مسموح به لكل قناة بين البيكسلات المتقابلة في الإطارات اللاحقة -h .................. هذه المساعدة -version ............ طباعة رقم الإصدار والخروج
مع تثبيت ملفات تطوير libgif ومترجم C++، يمكن بناء anim_diff باستخدام makefile.unix: $ make -f makefile.unix examples/anim_diff
أو باستخدام autoconf: $ ./configure --enable-everything $ make
وظائف التشفير الرئيسية متاحة في الملف الرأسي src/webp/encode.h الوظائف الجاهزة للاستخدام هي: size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output); size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride, float quality_factor, uint8_t** output); size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride, float quality_factor, uint8_t** output); size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride, float quality_factor, uint8_t** output);
ستقوم بتحويل عينات RGB الخام إلى بيانات WebP. التحكم الوحيد المقدم هو عامل الجودة.
هناك بعض المتغيرات لاستخدام الصيغة غير المفقودة:
size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height, int stride, uint8_t** output); size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height, int stride, uint8_t** output); size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height, int stride, uint8_t** output); size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height, int stride, uint8_t** output);
بالطبع في هذه الحالة، لا حاجة لعامل الجودة لأن الضغط يحدث بدون فقدان لقيم الإدخال، على حساب أحجام إخراج أكبر.
توجد واجهة برمجة تطبيقات أكثر تقدمًا تعتمد على هياكل WebPConfig وWebPPicture.
يحتوي WebPConfig على إعدادات التشفير ولا يرتبط بصورة معينة. يحتوي WebPPicture على بيانات الإدخال، والتي سيتم استخدام بعض WebPConfig عليها للضغط. يبدو تدفق التشفير كالتالي:
-------------------------------------- بداية مثال شبه كود
#include <webp/encode.h>
// إعداد Config، بدءًا من إعداد مسبق وضبط بعض المعلمات الإضافية WebPConfig config; if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) return 0; // خطأ في الإصدار } // ... ضبط إضافي config.sns_strength = 90; config.filter_sharpness = 6; config_error = WebPValidateConfig(&config); // ليس إلزاميًا، لكنه مفيد
// إعداد بيانات الإدخال WebPPicture pic; if (!WebPPictureInit(&pic)) { return 0; // خطأ في الإصدار } pic.width = width; pic.height = height; // تخصيص صورة بأبعاد width x height if (!WebPPictureAllocate(&pic)) { return 0; // خطأ في الذاكرة } // في هذه المرحلة، تم تهيئة 'pic' كحاوية، // ويمكنه استقبال عينات Y/U/V. // بدلاً من ذلك، يمكن استخدام وظائف الاستيراد الجاهزة مثل // WebPPictureImportRGB()، التي ستتولى تخصيص الذاكرة. // في أي حال، بعد هذه النقطة، يجب استدعاء // WebPPictureFree(&pic) لاستعادة الذاكرة.
// إعداد طريقة كتابة إخراج البايت. مثلاً WebPMemoryWriter. WebPMemoryWriter wrt; WebPMemoryWriterInit(&wrt); // تهيئة 'wrt'
pic.writer = MyFileWriter; pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
// ضغط! int ok = WebPEncode(&config, &pic); // ok = 0 => حدث خطأ! WebPPictureFree(&pic); // يجب استدعاؤها بغض النظر عن نتيجة 'ok'.
// يجب أن تكون بيانات الإخراج قد تم التعامل معها بواسطة الكاتب عند هذه النقطة. // -> البيانات المضغوطة هي مخزن الذاكرة الموصوف بواسطة wrt.mem / wrt.size
// تحرير الذاكرة المستخدمة بواسطة البيانات المضغوطة WebPMemoryWriterClear(&wrt);
-------------------------------------- نهاية مثال شبه كود
هذه بشكل أساسي مجرد دالة واحدة لاستدعائها:
#include "webp/decode.h" uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, int* width, int* height);
يرجى إلقاء نظرة على الملف src/webp/decode.h للحصول على التفاصيل. توجد متغيرات لفك التشفير بترتيب BGR/RGBA/ARGB/BGRA، بالإضافة إلى فك التشفير إلى عينات Y'CbCr الخام. يمكن أيضًا فك تشفير الصورة مباشرة إلى مخزن مخصص مسبقًا.
لاكتشاف ملف WebP وجمع أبعاد الصورة، يتم توفير الدالة: int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height); لا ينطوي استخدامها على أي فك تشفير.
في حالة نقل البيانات تدريجيًا، يمكن مع ذلك فك تشفير الصور بشكل تدريجي باستخدام واجهة برمجة تطبيقات أكثر تعقيدًا قليلاً. يتم تخزين حالة مفكك التشفير في مثيل من كائن WebPIDecoder. يمكن إنشاء هذا الكائن بهدف فك تشفير عينات RGB أو Y'CbCr. على سبيل المثال:
WebPDecBuffer buffer; WebPInitDecBuffer(&buffer); buffer.colorspace = MODE_BGR; ... WebPIDecoder* idec = WebPINewDecoder(&buffer);
عندما تصبح البيانات متاحة تدريجيًا، يمكن استخدام كائن مفكك التشفير التدريجي هذا لفك تشفير الصورة بشكل أكبر. هناك طريقتان (متنافيتان) لتمرير البيانات الواصلة حديثًا:
إما بإلحاق البايتات الجديدة:
WebPIAppend(idec, fresh_data, size_of_fresh_data);
أو بمجرد ذكر الحجم الجديد للبيانات المنقولة:
WebPIUpdate(idec, buffer, size_of_transmitted_buffer);
لاحظ أنه يمكن تعديل 'buffer' بين كل استدعاء لـ WebPIUpdate، خاصة عندما يتم تغيير حجم المخزن لاستيعاب بيانات أكبر.
ستعيد هذه الدوال حالة فك التشفير: إما VP8_STATUS_SUSPENDED إذا لم ينته فك التشفير بعد أو VP8_STATUS_OK عند الانتهاء من فك التشفير. أي حالة أخرى هي حالة خطأ.
يجب دائمًا تحرير كائن 'idec' (حتى في حالة وجود خطأ) عن طريق استدعاء: WebPDelete(idec).
لاسترداد عينات الصورة المفكوكة جزئيًا، يجب استخدام الطريقة المناظرة: WebPIDecGetRGB أو WebPIDecGetYUVA. ستعيد آخر صف بكسل قابل للعرض.
أخيرًا، لاحظ أن فك التشفير يمكن أيضًا إجراؤه في مخزن بكسل مخصص مسبقًا. يجب تمرير هذا المخزن عند إنشاء WebPIDecoder، عن طريق استدعاء WebPINewRGB() أو WebPINewYUVA().
يرجى إلقاء نظرة على الملف الرأسي src/webp/decode.h لمزيد من التفاصيل.
يدعم فك تشفير WebP واجهة برمجة تطبيقات متقدمة توفر اقتصاصًا وتغيير حجم في الوقت الفعلي، وهو أمر ذو فائدة كبيرة في البيئات المحدودة الذاكرة مثل الهواتف المحمولة. بشكل أساسي، سيتناسب استخدام الذاكرة مع حجم الإخراج، وليس الإدخال، عندما يحتاج المرء فقط إلى معاينة سريعة أو جزء مكبر من صورة كبيرة جدًا. يمكن أيضًا توفير بعض وحدة المعالجة المركزية (CPU) بالصدفة.
-------------------------------------- بداية مثال شبه كود // أ) تهيئة كائن التكوين WebPDecoderConfig config; CHECK(WebPInitDecoderConfig(&config));
// ب) اختياري: استرداد ميزات التدفق البتري.
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
// ج) ضبط خيارات 'config'، إذا لزم الأمر
config.options.no_fancy_upsampling = 1;
config.options.use_scaling = 1;
config.options.scaled_width = scaledWidth();
config.options.scaled_height = scaledHeight();
// إلخ.
// د) تحديد خيارات إخراج 'config' لتحديد فضاء الألوان للإخراج.
// اختياريًا، يمكن أيضًا تحديد مخزن فك تشفير الصورة الخارجي.
config.output.colorspace = MODE_BGRA;
// اختياريًا، يمكن توجيه config.output إلى مخزن خارجي أيضًا
// لفك تشفير الصورة. يجب أن يكون مخزن الذاكرة المقدم خارجيًا
// كبيرًا بما يكفي لتخزين الصورة المفكوكة.
config.output.u.RGBA.rgba = (uint8_t*) memory_buffer;
config.output.u.RGBA.stride = scanline_stride;
config.output.u.RGBA.size = total_size_of_the_memory_buffer;
config.output.is_external_memory = 1;
// هـ) فك تشفير صورة WebP. هناك نوعان فيما يتعلق بفك تشفير الصورة.
// الأول (هـ.1) يفك تشفير الصورة الكاملة والثاني (هـ.2) يُستخدم
// لفك تشفير الصورة تدريجيًا باستخدام مخازن إدخال صغيرة.
// يمكن استخدام أي من هذه الخطوات لفك تشفير صورة WebP.
// هـ.1) فك تشفير الصورة الكاملة.
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
// هـ.2) فك تشفير الصورة تدريجيًا.
WebPIDecoder* const idec = WebPIDecode(NULL, NULL, &config);
CHECK(idec != NULL);
while (bytes_remaining > 0) {
VP8StatusCode status = WebPIAppend(idec, input, bytes_read);
if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
bytes_remaining -= bytes_read;
} else {
break;
}
}
WebPIDelete(idec);
// و) الصورة المفكوكة الآن في config.output (و config.output.u.RGBA).
// يمكن حفظها أو عرضها أو معالجتها بخلاف ذلك.
// ز) استعادة الذاكرة المخصصة في كائن config. من الآمن استدعاء
// هذه الدالة حتى لو كانت الذاكرة خارجية ولم يتم تخصيصها
// بواسطة WebPDecode().
WebPFreeDecBuffer(&config.output);
-------------------------------------- نهاية مثال شبه كود
يرجى الإبلاغ عن جميع الأخطاء إلى متتبع المشكلات: https://bugs.chromium.org/p/webp نرحب بالتصحيحات! راجع هذه الصفحة للبدء: http://www.webmproject.org/code/contribute/submitting-patches/
البريد الإلكتروني: [email protected] الويب: http://groups.google.com/a/webmproject.org/group/webp-discuss