diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-08-20 09:07:09 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-08-20 09:07:09 +0300 |
commit | e9e496ffb64d83a55162d38ffc6d87a364bb6a95 (patch) | |
tree | a8a76c8bf63b24347e5d09582319db5eca4e7d88 /src | |
parent | 4e62a21cea5781fc91ec5ef22710e0fe19badb3c (diff) |
Added WebP decoding using libwebp
Diffstat (limited to 'src')
-rw-r--r-- | src/gmdocument.c | 5 | ||||
-rw-r--r-- | src/gmutil.c | 54 | ||||
-rw-r--r-- | src/gmutil.h | 1 | ||||
-rw-r--r-- | src/media.c | 16 | ||||
-rw-r--r-- | src/ui/documentwidget.c | 30 |
5 files changed, 74 insertions, 32 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c index 6ed628de..75f6f06b 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c | |||
@@ -240,7 +240,10 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li | |||
240 | iString *path = newRange_String(parts.path); | 240 | iString *path = newRange_String(parts.path); |
241 | if (endsWithCase_String(path, ".gif") || endsWithCase_String(path, ".jpg") || | 241 | if (endsWithCase_String(path, ".gif") || endsWithCase_String(path, ".jpg") || |
242 | endsWithCase_String(path, ".jpeg") || endsWithCase_String(path, ".png") || | 242 | endsWithCase_String(path, ".jpeg") || endsWithCase_String(path, ".png") || |
243 | endsWithCase_String(path, ".tga") || endsWithCase_String(path, ".psd") || | 243 | endsWithCase_String(path, ".tga") || endsWithCase_String(path, ".psd") || |
244 | #if defined (LAGRANGE_ENABLE_WEBP) | ||
245 | endsWithCase_String(path, ".webp") || | ||
246 | #endif | ||
244 | endsWithCase_String(path, ".hdr") || endsWithCase_String(path, ".pic")) { | 247 | endsWithCase_String(path, ".hdr") || endsWithCase_String(path, ".pic")) { |
245 | link->flags |= imageFileExtension_GmLinkFlag; | 248 | link->flags |= imageFileExtension_GmLinkFlag; |
246 | } | 249 | } |
diff --git a/src/gmutil.c b/src/gmutil.c index 9bd74ee0..d547d27d 100644 --- a/src/gmutil.c +++ b/src/gmutil.c | |||
@@ -511,54 +511,64 @@ const iString *findContainerArchive_Path(const iString *path) { | |||
511 | return NULL; | 511 | return NULL; |
512 | } | 512 | } |
513 | 513 | ||
514 | const char *mediaType_Path(const iString *path) { | 514 | const char *mediaTypeFromFileExtension_String(const iString *d) { |
515 | if (endsWithCase_String(path, ".gmi") || endsWithCase_String(path, ".gemini")) { | 515 | if (endsWithCase_String(d, ".gmi") || endsWithCase_String(d, ".gemini")) { |
516 | return "text/gemini; charset=utf-8"; | 516 | return "text/gemini; charset=utf-8"; |
517 | } | 517 | } |
518 | else if (endsWithCase_String(path, ".pem")) { | 518 | else if (endsWithCase_String(d, ".pem")) { |
519 | return "application/x-pem-file"; | 519 | return "application/x-pem-file"; |
520 | } | 520 | } |
521 | else if (endsWithCase_String(path, ".zip")) { | 521 | else if (endsWithCase_String(d, ".zip")) { |
522 | return "application/zip"; | 522 | return "application/zip"; |
523 | } | 523 | } |
524 | else if (endsWithCase_String(path, ".gpub")) { | 524 | else if (endsWithCase_String(d, ".gpub")) { |
525 | return "application/gpub+zip"; | 525 | return "application/gpub+zip"; |
526 | } | 526 | } |
527 | else if (endsWithCase_String(path, ".xml")) { | 527 | else if (endsWithCase_String(d, ".xml")) { |
528 | return "text/xml"; | 528 | return "text/xml"; |
529 | } | 529 | } |
530 | else if (endsWithCase_String(path, ".png")) { | 530 | else if (endsWithCase_String(d, ".png")) { |
531 | return "image/png"; | 531 | return "image/png"; |
532 | } | 532 | } |
533 | else if (endsWithCase_String(path, ".jpg") || endsWithCase_String(path, ".jpeg")) { | 533 | else if (endsWithCase_String(d, ".webp")) { |
534 | return "image/webp"; | ||
535 | } | ||
536 | else if (endsWithCase_String(d, ".jpg") || endsWithCase_String(d, ".jpeg")) { | ||
534 | return "image/jpeg"; | 537 | return "image/jpeg"; |
535 | } | 538 | } |
536 | else if (endsWithCase_String(path, ".gif")) { | 539 | else if (endsWithCase_String(d, ".gif")) { |
537 | return "image/gif"; | 540 | return "image/gif"; |
538 | } | 541 | } |
539 | else if (endsWithCase_String(path, ".wav")) { | 542 | else if (endsWithCase_String(d, ".wav")) { |
540 | return "audio/wave"; | 543 | return "audio/wave"; |
541 | } | 544 | } |
542 | else if (endsWithCase_String(path, ".ogg")) { | 545 | else if (endsWithCase_String(d, ".ogg")) { |
543 | return "audio/ogg"; | 546 | return "audio/ogg"; |
544 | } | 547 | } |
545 | else if (endsWithCase_String(path, ".mp3")) { | 548 | else if (endsWithCase_String(d, ".mp3")) { |
546 | return "audio/mpeg"; | 549 | return "audio/mpeg"; |
547 | } | 550 | } |
548 | else if (endsWithCase_String(path, ".mid")) { | 551 | else if (endsWithCase_String(d, ".mid")) { |
549 | return "audio/midi"; | 552 | return "audio/midi"; |
550 | } | 553 | } |
551 | else if (endsWithCase_String(path, ".txt") || | 554 | else if (endsWithCase_String(d, ".txt") || |
552 | endsWithCase_String(path, ".md") || | 555 | endsWithCase_String(d, ".md") || |
553 | endsWithCase_String(path, ".c") || | 556 | endsWithCase_String(d, ".c") || |
554 | endsWithCase_String(path, ".h") || | 557 | endsWithCase_String(d, ".h") || |
555 | endsWithCase_String(path, ".cc") || | 558 | endsWithCase_String(d, ".cc") || |
556 | endsWithCase_String(path, ".hh") || | 559 | endsWithCase_String(d, ".hh") || |
557 | endsWithCase_String(path, ".cpp") || | 560 | endsWithCase_String(d, ".cpp") || |
558 | endsWithCase_String(path, ".hpp")) { | 561 | endsWithCase_String(d, ".hpp")) { |
559 | return "text/plain"; | 562 | return "text/plain"; |
560 | } | 563 | } |
561 | const char *mtype = "application/octet-stream"; | 564 | return "application/octet-stream"; |
565 | } | ||
566 | |||
567 | const char *mediaType_Path(const iString *path) { | ||
568 | const char *mtype = mediaTypeFromFileExtension_String(path); | ||
569 | if (iCmpStr(mtype, "application/octet-stream")) { | ||
570 | return mtype; /* extension recognized */ | ||
571 | } | ||
562 | /* If the file is reasonably small and looks like UTF-8, we'll display it as text/plain. */ | 572 | /* If the file is reasonably small and looks like UTF-8, we'll display it as text/plain. */ |
563 | if (fileExists_FileInfo(path) && fileSize_FileInfo(path) <= 5000000) { | 573 | if (fileExists_FileInfo(path) && fileSize_FileInfo(path) <= 5000000) { |
564 | iFile *f = new_File(path); | 574 | iFile *f = new_File(path); |
diff --git a/src/gmutil.h b/src/gmutil.h index f8491781..3c10d45b 100644 --- a/src/gmutil.h +++ b/src/gmutil.h | |||
@@ -133,6 +133,7 @@ const iString * withSpacesEncoded_String(const iString *); | |||
133 | const iString * canonicalUrl_String (const iString *); | 133 | const iString * canonicalUrl_String (const iString *); |
134 | 134 | ||
135 | const char * mediaType_Path (const iString *path); | 135 | const char * mediaType_Path (const iString *path); |
136 | const char * mediaTypeFromFileExtension_String (const iString *); | ||
136 | iRangecc mediaTypeWithoutParameters_Rangecc (iRangecc mime); | 137 | iRangecc mediaTypeWithoutParameters_Rangecc (iRangecc mime); |
137 | 138 | ||
138 | const iString * findContainerArchive_Path (const iString *path); | 139 | const iString * findContainerArchive_Path (const iString *path); |
diff --git a/src/media.c b/src/media.c index eb4a8311..5240ab5d 100644 --- a/src/media.c +++ b/src/media.c | |||
@@ -30,6 +30,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
30 | #include "stb_image.h" | 30 | #include "stb_image.h" |
31 | #include "stb_image_resize.h" | 31 | #include "stb_image_resize.h" |
32 | 32 | ||
33 | #if defined (LAGRANGE_ENABLE_WEBP) | ||
34 | # include <webp/decode.h> | ||
35 | #endif | ||
36 | |||
33 | #include <the_Foundation/file.h> | 37 | #include <the_Foundation/file.h> |
34 | #include <the_Foundation/ptrarray.h> | 38 | #include <the_Foundation/ptrarray.h> |
35 | #include <SDL_hints.h> | 39 | #include <SDL_hints.h> |
@@ -86,8 +90,16 @@ void deinit_GmImage(iGmImage *d) { | |||
86 | void makeTexture_GmImage(iGmImage *d) { | 90 | void makeTexture_GmImage(iGmImage *d) { |
87 | iBlock *data = &d->partialData; | 91 | iBlock *data = &d->partialData; |
88 | d->numBytes = size_Block(data); | 92 | d->numBytes = size_Block(data); |
89 | uint8_t *imgData = stbi_load_from_memory( | 93 | uint8_t *imgData = NULL; |
90 | constData_Block(data), size_Block(data), &d->size.x, &d->size.y, NULL, 4); | 94 | if (cmp_String(&d->props.mime, "image/webp") == 0) { |
95 | #if defined (LAGRANGE_ENABLE_WEBP) | ||
96 | imgData = WebPDecodeRGBA(constData_Block(data), size_Block(data), &d->size.x, &d->size.y); | ||
97 | #endif | ||
98 | } | ||
99 | else { | ||
100 | imgData = stbi_load_from_memory( | ||
101 | constData_Block(data), size_Block(data), &d->size.x, &d->size.y, NULL, 4); | ||
102 | } | ||
91 | if (!imgData) { | 103 | if (!imgData) { |
92 | d->size = zero_I2(); | 104 | d->size = zero_I2(); |
93 | d->texture = NULL; | 105 | d->texture = NULL; |
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 3f655db5..83f38dee 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -1168,13 +1168,25 @@ static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode | |||
1168 | iString *key = collectNew_String(); | 1168 | iString *key = collectNew_String(); |
1169 | toString_Sym(SDLK_s, KMOD_PRIMARY, key); | 1169 | toString_Sym(SDLK_s, KMOD_PRIMARY, key); |
1170 | appendFormat_String(src, "\n```\n%s\n```\n", cstr_String(meta)); | 1170 | appendFormat_String(src, "\n```\n%s\n```\n", cstr_String(meta)); |
1171 | makeFooterButtons_DocumentWidget_( | 1171 | const char *mtype = mediaTypeFromFileExtension_String(d->mod.url); |
1172 | d, | 1172 | iArray items; |
1173 | (iMenuItem[]){ { translateCStr_Lang(download_Icon " " saveToDownloads_Label), | 1173 | init_Array(&items, sizeof(iMenuItem)); |
1174 | 0, | 1174 | if (iCmpStr(mtype, "application/octet-stream")) { |
1175 | 0, | 1175 | pushBack_Array( |
1176 | "document.save" } }, | 1176 | &items, |
1177 | 1); | 1177 | &(iMenuItem){ translateCStr_Lang(format_CStr("View as \"%s\"", mtype)), |
1178 | SDLK_RETURN, | ||
1179 | 0, | ||
1180 | format_CStr("document.setmediatype mime:%s", mtype) }); | ||
1181 | } | ||
1182 | pushBack_Array( | ||
1183 | &items, | ||
1184 | &(iMenuItem){ translateCStr_Lang(download_Icon " " saveToDownloads_Label), | ||
1185 | 0, | ||
1186 | 0, | ||
1187 | "document.save" }); | ||
1188 | makeFooterButtons_DocumentWidget_(d, data_Array(&items), size_Array(&items)); | ||
1189 | deinit_Array(&items); | ||
1178 | break; | 1190 | break; |
1179 | } | 1191 | } |
1180 | default: | 1192 | default: |
@@ -3176,6 +3188,10 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) | |||
3176 | document_App() == d) { | 3188 | document_App() == d) { |
3177 | return handleSwipe_DocumentWidget_(d, cmd); | 3189 | return handleSwipe_DocumentWidget_(d, cmd); |
3178 | } | 3190 | } |
3191 | else if (equal_Command(cmd, "document.setmediatype") && document_App() == d) { | ||
3192 | setUrlAndSource_DocumentWidget(d, d->mod.url, string_Command(cmd, "mime"), &d->sourceContent); | ||
3193 | return iTrue; | ||
3194 | } | ||
3179 | return iFalse; | 3195 | return iFalse; |
3180 | } | 3196 | } |
3181 | 3197 | ||