diff --git a/Makefile.in b/Makefile.in index 31e4672..78c3bb4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -33,6 +33,7 @@ all: ${PRPL_LIBNAME} ${LOCALES} PLUGIN_DIR_PURPLE=$(shell ${PKG_CONFIG} --variable=plugindir purple) DATA_ROOT_DIR_PURPLE=$(shell ${PKG_CONFIG} --variable=datarootdir purple) +COPY_ICONS=@COPY_ICONS@ create_dirs: ${DIR_LIST} @@ -76,28 +77,30 @@ strip: $(PRPL_LIBNAME) $(STRIP) --strip-unneeded $(PRPL_LIBNAME) .PHONY: install -install: $(PRPL_LIBNAME) +install: $(PRPL_LIBNAME) $(LOCALES) mkdir -m $(DIR_PERM) -p $(DESTDIR)$(PLUGIN_DIR_PURPLE) install -m $(FILE_PERM) $(PRPL_LIBNAME) $(DESTDIR)$(PLUGIN_DIR_PURPLE)/$(PRPL_NAME) mkdir -m $(DIR_PERM) -p $(DESTDIR)/etc/telegram-purple install -m $(FILE_PERM) tg-server.tglpub $(DESTDIR)/etc/telegram-purple/server.tglpub +ifeq ($(COPY_ICONS),no) + @echo "Not copying icons due to configure-option --disable-icons." + @echo " If you're using Finch, Empathy, or Telepathy, then this is a good idea." + @echo " If you're using Pidgin, then this is a bad idea." + @echo " If you're using Adium, read the README.md: You're using the wrong build system!" +else mkdir -m $(DIR_PERM) -p $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/16 install -m $(FILE_PERM) imgs/telegram16.png $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/16/telegram.png mkdir -m $(DIR_PERM) -p $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/22 install -m $(FILE_PERM) imgs/telegram22.png $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/22/telegram.png mkdir -m $(DIR_PERM) -p $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/48 install -m $(FILE_PERM) imgs/telegram48.png $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/48/telegram.png +endif @for lang in $(shell cat po/LINGUAS); do \ mkdir -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES; \ echo "installing po/$$lang.mo to $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(gettext_package).mo"; \ install -m $(FILE_PERM) po/$$lang.mo $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(gettext_package).mo; \ done -.PHONY: local_install -local_install: - mkdir -m $(DIR_PERM) -p ${HOME}/.purple/plugins/$(PRPL_NAME) - install $(PRPL_LIBNAME) ${HOME}/.purple/plugins/$(PRPL_NAME) - .PHONY: uninstall uninstall: rm -f $(DESTDIR)$(PLUGIN_DIR_PURPLE)/$(PRPL_NAME) @@ -106,12 +109,25 @@ uninstall: rm -f $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/16/telegram.png rm -f $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/22/telegram.png rm -f $(DESTDIR)$(DATA_ROOT_DIR_PURPLE)/pixmaps/pidgin/protocols/48/telegram.png - rm -f ${HOME}/.purple/plugins/$(PRPL_NAME) - for lang in $(shell cat po/LINGUAS); do \ +# TODO: Delete all installed .mo's, no matter what LINGUAS says. + @for lang in $(shell cat po/LINGUAS); do \ echo "removing $(localedir)/$$lang/LC_MESSAGES/$(gettext_package).mo"; \ rm -f $(localedir)/$$lang/LC_MESSAGES/$(gettext_package).mo; \ done +.PHONY: local_install +local_install: + mkdir -m $(DIR_PERM) -p $(DESTDIR)$(HOME)/.purple/plugins + install -m $(FILE_PERM) $(PRPL_LIBNAME) $(DESTDIR)$(HOME)/.purple/plugins/$(PRPL_NAME) +# See telegram-base.c, function get_user_pk_path for justification: + mkdir -m $(DIR_PERM) -p $(DESTDIR)$(HOME)/.purple/telegram-purple + install -m $(FILE_PERM) tg-server.tglpub $(DESTDIR)$(HOME)/.purple/telegram-purple/server.tglpub + +.PHONY: local_uninstall +local_uninstall: + rm -f $(DESTDIR)$(HOME)/.purple/plugins/$(PRPL_NAME) + rm -f $(DESTDIR)$(HOME)/.purple/telegram-purple/server.tglpub + .PHONY: run run: pidgin -d | grep 'telegram\|plugin\|proxy' diff --git a/README.md b/README.md index f3ac0f2..0838d36 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,11 @@ I keep getting many questions about this plugin in my E-mail, so I've created a [telegram group chat](https://telegram.me/joinchat/01fb53f301b67d3c7a5532908dfa9a89) for telegram-purple related discussions or questions. +OS Support +---------- + +This plugin is tested and works on **Linux** and **OS X**. As of right now, **Windows is not supported** although there's a plan to port it in the near future. + 1.2.2 ----- @@ -36,6 +41,12 @@ This repository has submodules, so you need to clone recursively. ###### Debian / Ubuntu +We are working on a Debian package! Please first check if it's already available to you: `sudo apt-get install telegram-purple` + +If the above works, then you should stop here: It is now installed. + +If the above fails: Don't worry, just continue building it by yourself. Next you need to install these dependencies: + sudo apt-get install libgcrypt20-dev libpurple-dev libwebp-dev ###### OpenSUSE @@ -48,6 +59,7 @@ And the development files for gcrypt, probably `gcrypt-devel` or something. #### 3. Compile and install If libwebp is not available, you can disable sticker support by calling ./configure --disable-libweb instead. +Please note that this is usually not necessary. ./configure make @@ -151,6 +163,47 @@ Compiling with XCode is a little bit problematic, since it requires you to compi 7. Build the XCode-Project and execute the created bundle +Building the Debian Package +--------------------------- + +If you just need a `.deb`, simply do: + + git checkout debian-master + fakeroot ./debian/rules binary + +And you're done! The `.deb` is in the directory at which you started. +To show some info about it, try this: + + dpkg --info telegram-purple_*.deb + +`debian-master` always points to a version that was submitted to Debian. (Note that this doesn't exist yet, as we haven't released to Debian yet.) +`debian-develop` is the candidate for the next submission. + +#### Debian Maintainers #### + +If you're a maintainer (if you're not sure, then you aren't a +maintainer), you need to produce a lot more files than that. + +Here's how you can generate a `.orig.tar.gz`: + + debian/genorigtar.sh + +This command requires the original tar to exist (and will fail otherwise, +although the error message will be misleading) will build all further files, +specifically `.debian.tar.xz`,`.dsc`, `.deb`, and `.changes`: + + dpkg-buildpackage + +And that already covers the official part of the work-flow. Of course, +you can call small parts of the build process directly, in order to avoid +overhead like rebuilding. For example, if you only need the `.debian.tar.xz` +and `.dsc` files, do this: + + debian/genorigtar.sh + ( cd .. && dpkg-source -b telegram-purple ) + +Note that the parenthesis are important. + Discussion / Help ----------------- @@ -196,6 +249,6 @@ Telegram-Purple was written by: Acknowledgements ---------------- -This software is based on the library [Libtgl](https://github.com/vysheng/tgl), which was written by Vitaly Valtman and others, see (http://github.com/vysheng/tgl) +This software is based on the library [Libtgl](https://github.com/vysheng/tgl), which was written by Vitaly Valtman and others, see (https://github.com/vysheng/tgl/) For PNG rendering, it includes the [lodepng library](http://lodev.org/lodepng/). diff --git a/autogen.sh b/autogen.sh index 26ebbae..3650700 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,17 +1,20 @@ -autoheader -autoconf +#!/bin/sh + +autoreconf echo bootstrapping translation files ... cd po intltool-update --pot -for lang in $(cat LINGUAS); do - if [ -e "$lang.po" ] - then - echo "updating language file $lang.po ..." - intltool-update "$lang" - else - echo "creating new language file $lang.po ..." - msginit --locale="$lang" - fi -done +## Translations are managed at https://www.transifex.com/telegram-purple-developers/telegram-purple/ +## To update the .po files, download it from there, since intltool, msginit, and transifex produce slightly different files, and I'd like to avoid gigantic git diffs that only change indentation or similar things. +#for lang in $(cat LINGUAS); do +# if [ -e "$lang.po" ] +# then +# echo "updating language file $lang.po ..." +# intltool-update "$lang" +# else +# echo "creating new language file $lang.po ..." +# msginit --locale="$lang" +# fi +#done cd .. diff --git a/configure b/configure index 992a1b3..d95ea2c 100755 --- a/configure +++ b/configure @@ -624,6 +624,7 @@ GETTEXT_PACKAGE GETTEXT_CHECK PURPLE_CPPFLAGS LIBOBJS +COPY_ICONS PURPLE_LIBS PURPLE_CFLAGS PKG_CONFIG_LIBDIR @@ -685,6 +686,7 @@ ac_user_opts=' enable_option_checking with_zlib enable_libwebp +enable_icons ' ac_precious_vars='build_alias host_alias @@ -1311,6 +1313,10 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-libwebp Disable libwebp, stickers won't be displayed in the chat + --disable-icons Don't copy the protocol icons for Pidgin. Only + useful if you're using Finch of telepathy-haze. + (Adium users shouldn't be using this build system at + all.) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -4159,6 +4165,22 @@ else fi +fi + +COPY_ICONS=yes + +# Check whether --enable-icons was given. +if test "${enable_icons+set}" = set; then : + enableval=$enable_icons; +fi + + if test "x$enable_icons" == "xno"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Icons are deactivated. Pidgin needs icons. Finch and telepathy-haze don't." >&5 +$as_echo "$as_me: WARNING: Icons are deactivated. Pidgin needs icons. Finch and telepathy-haze don't." >&2;} + COPY_ICONS=no + + fi # Checks for header files. diff --git a/configure.ac b/configure.ac index 3cf0130..4764734 100644 --- a/configure.ac +++ b/configure.ac @@ -30,6 +30,14 @@ AC_ARG_ENABLE([libwebp], AC_CHECK_LIB([webp], [WebPDecodeRGBA], [], [AC_MSG_ERROR([no libwebp found, try --disable-libwebp, but stickers won't be displayed in the chat])]) ]) +AC_SUBST([COPY_ICONS], [yes]) +AC_ARG_ENABLE([icons], + AS_HELP_STRING([--disable-icons], [Don't copy the protocol icons for Pidgin. Only useful if you're using Finch of telepathy-haze. (Adium users shouldn't be using this build system at all.)])) + AS_IF([test "x$enable_icons" == "xno"], [ + AC_WARN([Icons are deactivated. Pidgin needs icons. Finch and telepathy-haze don't.]) + AC_SUBST([COPY_ICONS], [no]) + ]) + # Checks for header files. AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h unistd.h]) diff --git a/lodepng/lodepng.c b/lodepng/lodepng.c index 2be3fbe..fbcecb5 100644 --- a/lodepng/lodepng.c +++ b/lodepng/lodepng.c @@ -1,7 +1,7 @@ /* -LodePNG version 20140823 +LodePNG version 20150912 -Copyright (c) 2005-2014 Lode Vandevenne +Copyright (c) 2005-2015 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,13 +37,13 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for #include #endif /*LODEPNG_COMPILE_CPP*/ -#define VERSION_STRING "20140823" - #if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/ #pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ #pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ #endif /*_MSC_VER */ +const char* LODEPNG_VERSION_STRING = "20150912"; + /* This source file is built up in the following large parts. The code sections with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way. @@ -119,6 +119,13 @@ Example: if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83); if(error) return error;\ } +/*Set error var to the error code, and return from the void function.*/ +#define CERROR_RETURN(errorvar, code)\ +{\ + errorvar = code;\ + return;\ +} + /* About uivector, ucvector and string: -All of them wrap dynamic arrays or text strings in a similar way. @@ -174,7 +181,7 @@ static unsigned uivector_resizev(uivector* p, size_t size, unsigned value) { size_t oldsize = p->size, i; if(!uivector_resize(p, size)) return 0; - for(i = oldsize; i < size; i++) p->data[i] = value; + for(i = oldsize; i < size; ++i) p->data[i] = value; return 1; } @@ -192,15 +199,6 @@ static unsigned uivector_push_back(uivector* p, unsigned c) p->data[p->size - 1] = c; return 1; } - -/*copy q to p, returns 1 if success, 0 if failure ==> nothing done*/ -static unsigned uivector_copy(uivector* p, const uivector* q) -{ - size_t i; - if(!uivector_resize(p, q->size)) return 0; - for(i = 0; i < q->size; i++) p->data[i] = q->data[i]; - return 1; -} #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_ZLIB*/ @@ -260,7 +258,7 @@ static unsigned ucvector_resizev(ucvector* p, size_t size, unsigned char value) { size_t oldsize = p->size, i; if(!ucvector_resize(p, size)) return 0; - for(i = oldsize; i < size; i++) p->data[i] = value; + for(i = oldsize; i < size; ++i) p->data[i] = value; return 1; } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -319,10 +317,10 @@ static void string_cleanup(char** out) static void string_set(char** out, const char* in) { - size_t insize = strlen(in), i = 0; + size_t insize = strlen(in), i; if(string_resize(out, insize)) { - for(i = 0; i < insize; i++) + for(i = 0; i != insize; ++i) { (*out)[i] = in[i]; } @@ -418,19 +416,19 @@ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const if(((*bitpointer) & 7) == 0) ucvector_push_back(bitstream, (unsigned char)0);\ /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/\ (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7));\ - (*bitpointer)++;\ + ++(*bitpointer);\ } static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) { size_t i; - for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1)); + for(i = 0; i != nbits; ++i) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1)); } static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) { size_t i; - for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1)); + for(i = 0; i != nbits; ++i) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1)); } #endif /*LODEPNG_COMPILE_ENCODER*/ @@ -441,17 +439,17 @@ static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, uns static unsigned char readBitFromStream(size_t* bitpointer, const unsigned char* bitstream) { unsigned char result = (unsigned char)(READBIT(*bitpointer, bitstream)); - (*bitpointer)++; + ++(*bitpointer); return result; } static unsigned readBitsFromStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) { unsigned result = 0, i; - for(i = 0; i < nbits; i++) + for(i = 0; i != nbits; ++i) { result += ((unsigned)READBIT(*bitpointer, bitstream)) << i; - (*bitpointer)++; + ++(*bitpointer); } return result; } @@ -514,7 +512,7 @@ typedef struct HuffmanTree static void HuffmanTree_draw(HuffmanTree* tree) { std::cout << "tree. length: " << tree->numcodes << " maxbitlen: " << tree->maxbitlen << std::endl; - for(size_t i = 0; i < tree->tree1d.size; i++) + for(size_t i = 0; i != tree->tree1d.size; ++i) { if(tree->lengths.data[i]) std::cout << i << " " << tree->tree1d.data[i] << " " << tree->lengths.data[i] << std::endl; @@ -556,17 +554,18 @@ static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) There is only memory for such good tree currently, if there are more nodes (due to too long length codes), error 55 will happen */ - for(n = 0; n < tree->numcodes * 2; n++) + for(n = 0; n < tree->numcodes * 2; ++n) { tree->tree2d[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/ } - for(n = 0; n < tree->numcodes; n++) /*the codes*/ + for(n = 0; n < tree->numcodes; ++n) /*the codes*/ { - for(i = 0; i < tree->lengths[n]; i++) /*the bits for this code*/ + for(i = 0; i != tree->lengths[n]; ++i) /*the bits for this code*/ { unsigned char bit = (unsigned char)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1); - if(treepos > tree->numcodes - 2) return 55; /*oversubscribed, see comment in lodepng_error_text*/ + /*oversubscribed, see comment in lodepng_error_text*/ + if(treepos > 2147483647 || treepos + 2 > tree->numcodes) return 55; if(tree->tree2d[2 * treepos + bit] == 32767) /*not yet filled in*/ { if(i + 1 == tree->lengths[n]) /*last bit*/ @@ -578,7 +577,7 @@ static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) { /*put address of the next step in here, first that address has to be found of course (it's just nodefilled + 1)...*/ - nodefilled++; + ++nodefilled; /*addresses encoded with numcodes added to it*/ tree->tree2d[2 * treepos + bit] = nodefilled + tree->numcodes; treepos = nodefilled; @@ -588,7 +587,7 @@ static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) } } - for(n = 0; n < tree->numcodes * 2; n++) + for(n = 0; n < tree->numcodes * 2; ++n) { if(tree->tree2d[n] == 32767) tree->tree2d[n] = 0; /*remove possible remaining 32767's*/ } @@ -605,7 +604,8 @@ static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) { uivector blcount; uivector nextcode; - unsigned bits, n, error = 0; + unsigned error = 0; + unsigned bits, n; uivector_init(&blcount); uivector_init(&nextcode); @@ -620,14 +620,14 @@ static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) if(!error) { /*step 1: count number of instances of each code length*/ - for(bits = 0; bits < tree->numcodes; bits++) blcount.data[tree->lengths[bits]]++; + for(bits = 0; bits != tree->numcodes; ++bits) ++blcount.data[tree->lengths[bits]]; /*step 2: generate the nextcode values*/ - for(bits = 1; bits <= tree->maxbitlen; bits++) + for(bits = 1; bits <= tree->maxbitlen; ++bits) { nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1; } /*step 3: generate all the codes*/ - for(n = 0; n < tree->numcodes; n++) + for(n = 0; n != tree->numcodes; ++n) { if(tree->lengths[n] != 0) tree->tree1d[n] = nextcode.data[tree->lengths[n]]++; } @@ -651,7 +651,7 @@ static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* b unsigned i; tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); if(!tree->lengths) return 83; /*alloc fail*/ - for(i = 0; i < numcodes; i++) tree->lengths[i] = bitlen[i]; + for(i = 0; i != numcodes; ++i) tree->lengths[i] = bitlen[i]; tree->numcodes = (unsigned)numcodes; /*number of symbols*/ tree->maxbitlen = maxbitlen; return HuffmanTree_makeFromLengths2(tree); @@ -659,101 +659,136 @@ static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* b #ifdef LODEPNG_COMPILE_ENCODER -/* -A coin, this is the terminology used for the package-merge algorithm and the -coin collector's problem. This is used to generate the huffman tree. -A coin can be multiple coins (when they're merged) -*/ -typedef struct Coin +/*BPM: Boundary Package Merge, see "A Fast and Space-Economical Algorithm for Length-Limited Coding", +Jyrki Katajainen, Alistair Moffat, Andrew Turpin, 1995.*/ + +/*chain node for boundary package merge*/ +typedef struct BPMNode { - uivector symbols; - float weight; /*the sum of all weights in this coin*/ -} Coin; + int weight; /*the sum of all weights in this chain*/ + unsigned index; /*index of this leaf node (called "count" in the paper)*/ + struct BPMNode* tail; /*the next nodes in this chain (null if last)*/ + int in_use; +} BPMNode; -static void coin_init(Coin* c) +/*lists of chains*/ +typedef struct BPMLists { - uivector_init(&c->symbols); -} + /*memory pool*/ + unsigned memsize; + BPMNode* memory; + unsigned numfree; + unsigned nextfree; + BPMNode** freelist; + /*two heads of lookahead chains per list*/ + unsigned listsize; + BPMNode** chains0; + BPMNode** chains1; +} BPMLists; -/*argument c is void* so that this dtor can be given as function pointer to the vector resize function*/ -static void coin_cleanup(void* c) -{ - uivector_cleanup(&((Coin*)c)->symbols); -} - -static void coin_copy(Coin* c1, const Coin* c2) -{ - c1->weight = c2->weight; - uivector_copy(&c1->symbols, &c2->symbols); -} - -static void add_coins(Coin* c1, const Coin* c2) -{ - size_t i; - for(i = 0; i < c2->symbols.size; i++) uivector_push_back(&c1->symbols, c2->symbols.data[i]); - c1->weight += c2->weight; -} - -static void init_coins(Coin* coins, size_t num) -{ - size_t i; - for(i = 0; i < num; i++) coin_init(&coins[i]); -} - -static void cleanup_coins(Coin* coins, size_t num) -{ - size_t i; - for(i = 0; i < num; i++) coin_cleanup(&coins[i]); -} - -static int coin_compare(const void* a, const void* b) { - float wa = ((const Coin*)a)->weight; - float wb = ((const Coin*)b)->weight; - return wa > wb ? 1 : wa < wb ? -1 : 0; -} - -static unsigned append_symbol_coins(Coin* coins, const unsigned* frequencies, unsigned numcodes, size_t sum) +/*creates a new chain node with the given parameters, from the memory in the lists */ +static BPMNode* bpmnode_create(BPMLists* lists, int weight, unsigned index, BPMNode* tail) { unsigned i; - unsigned j = 0; /*index of present symbols*/ - for(i = 0; i < numcodes; i++) + BPMNode* result; + + /*memory full, so garbage collect*/ + if(lists->nextfree >= lists->numfree) { - if(frequencies[i] != 0) /*only include symbols that are present*/ + /*mark only those that are in use*/ + for(i = 0; i != lists->memsize; ++i) lists->memory[i].in_use = 0; + for(i = 0; i != lists->listsize; ++i) { - coins[j].weight = frequencies[i] / (float)sum; - uivector_push_back(&coins[j].symbols, i); - j++; + BPMNode* node; + for(node = lists->chains0[i]; node != 0; node = node->tail) node->in_use = 1; + for(node = lists->chains1[i]; node != 0; node = node->tail) node->in_use = 1; + } + /*collect those that are free*/ + lists->numfree = 0; + for(i = 0; i != lists->memsize; ++i) + { + if(!lists->memory[i].in_use) lists->freelist[lists->numfree++] = &lists->memory[i]; + } + lists->nextfree = 0; + } + + result = lists->freelist[lists->nextfree++]; + result->weight = weight; + result->index = index; + result->tail = tail; + return result; +} + +static int bpmnode_compare(const void* a, const void* b) +{ + int wa = ((const BPMNode*)a)->weight; + int wb = ((const BPMNode*)b)->weight; + if(wa < wb) return -1; + if(wa > wb) return 1; + /*make the qsort a stable sort*/ + return ((const BPMNode*)a)->index < ((const BPMNode*)b)->index ? 1 : -1; +} + +/*Boundary Package Merge step, numpresent is the amount of leaves, and c is the current chain.*/ +static void boundaryPM(BPMLists* lists, BPMNode* leaves, size_t numpresent, int c, int num) +{ + unsigned lastindex = lists->chains1[c]->index; + + if(c == 0) + { + if(lastindex >= numpresent) return; + lists->chains0[c] = lists->chains1[c]; + lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0); + } + else + { + /*sum of the weights of the head nodes of the previous lookahead chains.*/ + int sum = lists->chains0[c - 1]->weight + lists->chains1[c - 1]->weight; + lists->chains0[c] = lists->chains1[c]; + if(lastindex < numpresent && sum > leaves[lastindex].weight) + { + lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->chains1[c]->tail); + return; + } + lists->chains1[c] = bpmnode_create(lists, sum, lastindex, lists->chains1[c - 1]); + /*in the end we are only interested in the chain of the last list, so no + need to recurse if we're at the last one (this gives measurable speedup)*/ + if(num + 1 < (int)(2 * numpresent - 2)) + { + boundaryPM(lists, leaves, numpresent, c - 1, num); + boundaryPM(lists, leaves, numpresent, c - 1, num); } } - return 0; } unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, size_t numcodes, unsigned maxbitlen) { - unsigned i, j; - size_t sum = 0, numpresent = 0; unsigned error = 0; - Coin* coins; /*the coins of the currently calculated row*/ - Coin* prev_row; /*the previous row of coins*/ - size_t numcoins; - size_t coinmem; + unsigned i; + size_t numpresent = 0; /*number of symbols with non-zero frequency*/ + BPMNode* leaves; /*the symbols, only those with > 0 frequency*/ if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ + if((1u << maxbitlen) < numcodes) return 80; /*error: represent all symbols*/ - for(i = 0; i < numcodes; i++) + leaves = (BPMNode*)lodepng_malloc(numcodes * sizeof(*leaves)); + if(!leaves) return 83; /*alloc fail*/ + + for(i = 0; i != numcodes; ++i) { if(frequencies[i] > 0) { - numpresent++; - sum += frequencies[i]; + leaves[numpresent].weight = frequencies[i]; + leaves[numpresent].index = i; + ++numpresent; } } - for(i = 0; i < numcodes; i++) lengths[i] = 0; + for(i = 0; i != numcodes; ++i) lengths[i] = 0; /*ensure at least two present symbols. There should be at least one symbol - according to RFC 1951 section 3.2.7. To decoders incorrectly require two. To + according to RFC 1951 section 3.2.7. Some decoders incorrectly require two. To make these work as well ensure there are at least two symbols. The Package-Merge code below also doesn't work correctly if there's only one symbol, it'd give it the theoritical 0 bits but in practice zlib wants 1 bit*/ @@ -763,87 +798,55 @@ unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequen } else if(numpresent == 1) { - for(i = 0; i < numcodes; i++) - { - if(frequencies[i]) - { - lengths[i] = 1; - lengths[i == 0 ? 1 : 0] = 1; - break; - } - } + lengths[leaves[0].index] = 1; + lengths[leaves[0].index == 0 ? 1 : 0] = 1; } else { - /*Package-Merge algorithm represented by coin collector's problem - For every symbol, maxbitlen coins will be created*/ + BPMLists lists; + BPMNode* node; - coinmem = numpresent * 2; /*max amount of coins needed with the current algo*/ - coins = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem); - prev_row = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem); - if(!coins || !prev_row) - { - lodepng_free(coins); - lodepng_free(prev_row); - return 83; /*alloc fail*/ - } - init_coins(coins, coinmem); - init_coins(prev_row, coinmem); + qsort(leaves, numpresent, sizeof(BPMNode), bpmnode_compare); - /*first row, lowest denominator*/ - error = append_symbol_coins(coins, frequencies, numcodes, sum); - numcoins = numpresent; - qsort(coins, numcoins, sizeof(Coin), coin_compare); - if(!error) - { - unsigned numprev = 0; - for(j = 1; j <= maxbitlen && !error; j++) /*each of the remaining rows*/ - { - unsigned tempnum; - Coin* tempcoins; - /*swap prev_row and coins, and their amounts*/ - tempcoins = prev_row; prev_row = coins; coins = tempcoins; - tempnum = numprev; numprev = numcoins; numcoins = tempnum; - - cleanup_coins(coins, numcoins); - init_coins(coins, numcoins); - - numcoins = 0; - - /*fill in the merged coins of the previous row*/ - for(i = 0; i + 1 < numprev; i += 2) - { - /*merge prev_row[i] and prev_row[i + 1] into new coin*/ - Coin* coin = &coins[numcoins++]; - coin_copy(coin, &prev_row[i]); - add_coins(coin, &prev_row[i + 1]); - } - /*fill in all the original symbols again*/ - if(j < maxbitlen) - { - error = append_symbol_coins(coins + numcoins, frequencies, numcodes, sum); - numcoins += numpresent; - } - qsort(coins, numcoins, sizeof(Coin), coin_compare); - } - } + lists.listsize = maxbitlen; + lists.memsize = 2 * maxbitlen * (maxbitlen + 1); + lists.nextfree = 0; + lists.numfree = lists.memsize; + lists.memory = (BPMNode*)lodepng_malloc(lists.memsize * sizeof(*lists.memory)); + lists.freelist = (BPMNode**)lodepng_malloc(lists.memsize * sizeof(BPMNode*)); + lists.chains0 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); + lists.chains1 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); + if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83; /*alloc fail*/ if(!error) { - /*calculate the lenghts of each symbol, as the amount of times a coin of each symbol is used*/ - for(i = 0; i < numpresent - 1; i++) + for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i]; + + bpmnode_create(&lists, leaves[0].weight, 1, 0); + bpmnode_create(&lists, leaves[1].weight, 2, 0); + + for(i = 0; i != lists.listsize; ++i) { - Coin* coin = &coins[i]; - for(j = 0; j < coin->symbols.size; j++) lengths[coin->symbols.data[j]]++; + lists.chains0[i] = &lists.memory[0]; + lists.chains1[i] = &lists.memory[1]; + } + + /*each boundaryPM call adds one chain to the last list, and we need 2 * numpresent - 2 chains.*/ + for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, maxbitlen - 1, i); + + for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail) + { + for(i = 0; i != node->index; ++i) ++lengths[leaves[i].index]; } } - cleanup_coins(coins, coinmem); - lodepng_free(coins); - cleanup_coins(prev_row, coinmem); - lodepng_free(prev_row); + lodepng_free(lists.memory); + lodepng_free(lists.freelist); + lodepng_free(lists.chains0); + lodepng_free(lists.chains1); } + lodepng_free(leaves); return error; } @@ -852,7 +855,7 @@ static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigne size_t mincodes, size_t numcodes, unsigned maxbitlen) { unsigned error = 0; - while(!frequencies[numcodes - 1] && numcodes > mincodes) numcodes--; /*trim zeroes*/ + while(!frequencies[numcodes - 1] && numcodes > mincodes) --numcodes; /*trim zeroes*/ tree->maxbitlen = maxbitlen; tree->numcodes = (unsigned)numcodes; /*number of symbols*/ tree->lengths = (unsigned*)lodepng_realloc(tree->lengths, numcodes * sizeof(unsigned)); @@ -884,10 +887,10 @@ static unsigned generateFixedLitLenTree(HuffmanTree* tree) if(!bitlen) return 83; /*alloc fail*/ /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ - for(i = 0; i <= 143; i++) bitlen[i] = 8; - for(i = 144; i <= 255; i++) bitlen[i] = 9; - for(i = 256; i <= 279; i++) bitlen[i] = 7; - for(i = 280; i <= 287; i++) bitlen[i] = 8; + for(i = 0; i <= 143; ++i) bitlen[i] = 8; + for(i = 144; i <= 255; ++i) bitlen[i] = 9; + for(i = 256; i <= 279; ++i) bitlen[i] = 7; + for(i = 280; i <= 287; ++i) bitlen[i] = 8; error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15); @@ -903,7 +906,7 @@ static unsigned generateFixedDistanceTree(HuffmanTree* tree) if(!bitlen) return 83; /*alloc fail*/ /*there are 32 distance codes, but 30-31 are unused*/ - for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen[i] = 5; + for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen[i] = 5; error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15); lodepng_free(bitlen); @@ -928,7 +931,7 @@ static unsigned huffmanDecodeSymbol(const unsigned char* in, size_t* bp, the expression below because this is the biggest bottleneck while decoding */ ct = codetree->tree2d[(treepos << 1) + READBIT(*bp, in)]; - (*bp)++; + ++(*bp); if(ct < codetree->numcodes) return ct; /*the symbol is decoded, return it*/ else treepos = ct - codetree->numcodes; /*symbol not yet decoded, instead move tree position*/ @@ -967,7 +970,7 @@ static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, unsigned* bitlen_cl = 0; HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ - if((*bp) >> 3 >= inlength - 2) return 49; /*error: the bit pointer is or will go past the memory*/ + if((*bp) + 14 > (inlength << 3)) return 49; /*error: the bit pointer is or will go past the memory*/ /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ HLIT = readBitsFromStream(bp, in, 5) + 257; @@ -976,6 +979,8 @@ static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/ HCLEN = readBitsFromStream(bp, in, 4) + 4; + if((*bp) + HCLEN * 3 > (inlength << 3)) return 50; /*error: the bit pointer is or will go past the memory*/ + HuffmanTree_init(&tree_cl); while(!error) @@ -985,7 +990,7 @@ static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned)); if(!bitlen_cl) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < NUM_CODE_LENGTH_CODES; i++) + for(i = 0; i != NUM_CODE_LENGTH_CODES; ++i) { if(i < HCLEN) bitlen_cl[CLCL_ORDER[i]] = readBitsFromStream(bp, in, 3); else bitlen_cl[CLCL_ORDER[i]] = 0; /*if not, it must stay 0*/ @@ -998,8 +1003,8 @@ static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < NUM_DEFLATE_CODE_SYMBOLS; i++) bitlen_ll[i] = 0; - for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen_d[i] = 0; + for(i = 0; i != NUM_DEFLATE_CODE_SYMBOLS; ++i) bitlen_ll[i] = 0; + for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen_d[i] = 0; /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/ i = 0; @@ -1010,61 +1015,59 @@ static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, { if(i < HLIT) bitlen_ll[i] = code; else bitlen_d[i - HLIT] = code; - i++; + ++i; } else if(code == 16) /*repeat previous*/ { unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ unsigned value; /*set value to the previous code*/ - if(*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ - if (i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ + if(i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ + if((*bp + 2) > inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ replength += readBitsFromStream(bp, in, 2); if(i < HLIT + 1) value = bitlen_ll[i - 1]; else value = bitlen_d[i - HLIT - 1]; /*repeat this value in the next lengths*/ - for(n = 0; n < replength; n++) + for(n = 0; n < replength; ++n) { if(i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/ if(i < HLIT) bitlen_ll[i] = value; else bitlen_d[i - HLIT] = value; - i++; + ++i; } } else if(code == 17) /*repeat "0" 3-10 times*/ { unsigned replength = 3; /*read in the bits that indicate repeat length*/ - if(*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ - + if((*bp + 3) > inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ replength += readBitsFromStream(bp, in, 3); /*repeat this value in the next lengths*/ - for(n = 0; n < replength; n++) + for(n = 0; n < replength; ++n) { if(i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/ if(i < HLIT) bitlen_ll[i] = 0; else bitlen_d[i - HLIT] = 0; - i++; + ++i; } } else if(code == 18) /*repeat "0" 11-138 times*/ { unsigned replength = 11; /*read in the bits that indicate repeat length*/ - if(*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ - + if((*bp + 7) > inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ replength += readBitsFromStream(bp, in, 7); /*repeat this value in the next lengths*/ - for(n = 0; n < replength; n++) + for(n = 0; n < replength; ++n) { if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/ if(i < HLIT) bitlen_ll[i] = 0; else bitlen_d[i - HLIT] = 0; - i++; + ++i; } } else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ @@ -1123,7 +1126,7 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size /*ucvector_push_back would do the same, but for some reason the two lines below run 10% faster*/ if(!ucvector_resize(out, (*pos) + 1)) ERROR_BREAK(83 /*alloc fail*/); out->data[*pos] = (unsigned char)code_ll; - (*pos)++; + ++(*pos); } else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ { @@ -1136,7 +1139,7 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size /*part 2: get extra bits and add the value of that to length*/ numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; - if(*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ + if((*bp + numextrabits_l) > inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ length += readBitsFromStream(bp, in, numextrabits_l); /*part 3: get distance code*/ @@ -1156,8 +1159,7 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size /*part 4: get extra bits from distance*/ numextrabits_d = DISTANCEEXTRA[code_d]; - if(*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ - + if((*bp + numextrabits_d) > inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ distance += readBitsFromStream(bp, in, numextrabits_d); /*part 5: fill in all the out[n] values based on the length and dist*/ @@ -1166,12 +1168,14 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size backward = start - distance; if(!ucvector_resize(out, (*pos) + length)) ERROR_BREAK(83 /*alloc fail*/); - for(forward = 0; forward < length; forward++) - { - out->data[(*pos)] = out->data[backward]; - (*pos)++; - backward++; - if(backward >= start) backward = start - distance; + if (distance < length) { + for(forward = 0; forward < length; ++forward) + { + out->data[(*pos)++] = out->data[backward++]; + } + } else { + memcpy(out->data + *pos, out->data + backward, length); + *pos += length; } } else if(code_ll == 256) @@ -1182,7 +1186,7 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size { /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ - error = (*bp) > inlength * 8 ? 10 : 11; + error = ((*bp) > inlength * 8) ? 10 : 11; break; } } @@ -1195,14 +1199,15 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size static unsigned inflateNoCompression(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength) { - /*go to first boundary of byte*/ size_t p; unsigned LEN, NLEN, n, error = 0; - while(((*bp) & 0x7) != 0) (*bp)++; + + /*go to first boundary of byte*/ + while(((*bp) & 0x7) != 0) ++(*bp); p = (*bp) / 8; /*byte position*/ /*read LEN (2 bytes) and NLEN (2 bytes)*/ - if(p >= inlength - 4) return 52; /*error, bit pointer will jump past memory*/ + if(p + 4 >= inlength) return 52; /*error, bit pointer will jump past memory*/ LEN = in[p] + 256u * in[p + 1]; p += 2; NLEN = in[p] + 256u * in[p + 1]; p += 2; @@ -1213,7 +1218,7 @@ static unsigned inflateNoCompression(ucvector* out, const unsigned char* in, siz /*read the literal data: LEN bytes are now stored in the out buffer*/ if(p + LEN > inlength) return 23; /*error: reading outside of in buffer*/ - for(n = 0; n < LEN; n++) out->data[(*pos)++] = in[p++]; + for(n = 0; n < LEN; ++n) out->data[(*pos)++] = in[p++]; (*bp) = p * 8; @@ -1298,7 +1303,7 @@ given array must be sorted (if no value is smaller, it returns the size of the g static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) { /*linear search implementation*/ - /*for(size_t i = 1; i < array_size; i++) if(array[i] > value) return i - 1; + /*for(size_t i = 1; i < array_size; ++i) if(array[i] > value) return i - 1; return array_size - 1;*/ /*binary search implementation (not that much faster) (precondition: array_size > 0)*/ @@ -1369,12 +1374,12 @@ static unsigned hash_init(Hash* hash, unsigned windowsize) } /*initialize hash table*/ - for(i = 0; i < HASH_NUM_VALUES; i++) hash->head[i] = -1; - for(i = 0; i < windowsize; i++) hash->val[i] = -1; - for(i = 0; i < windowsize; i++) hash->chain[i] = i; /*same value as index indicates uninitialized*/ + for(i = 0; i != HASH_NUM_VALUES; ++i) hash->head[i] = -1; + for(i = 0; i != windowsize; ++i) hash->val[i] = -1; + for(i = 0; i != windowsize; ++i) hash->chain[i] = i; /*same value as index indicates uninitialized*/ - for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; i++) hash->headz[i] = -1; - for(i = 0; i < windowsize; i++) hash->chainz[i] = i; /*same value as index indicates uninitialized*/ + for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; ++i) hash->headz[i] = -1; + for(i = 0; i != windowsize; ++i) hash->chainz[i] = i; /*same value as index indicates uninitialized*/ return 0; } @@ -1395,7 +1400,7 @@ static void hash_cleanup(Hash* hash) static unsigned getHash(const unsigned char* data, size_t size, size_t pos) { unsigned result = 0; - if (pos + 2 < size) + if(pos + 2 < size) { /*A simple shift and xor hash is used. Since the data of PNGs is dominated by zeroes due to the filters, a better hash does not have a significant @@ -1408,7 +1413,7 @@ static unsigned getHash(const unsigned char* data, size_t size, size_t pos) size_t amount, i; if(pos >= size) return 0; amount = size - pos; - for(i = 0; i < amount; i++) result ^= (unsigned)(data[pos + i] << (i * 8u)); + for(i = 0; i != amount; ++i) result ^= (unsigned)(data[pos + i] << (i * 8u)); } return result & HASH_BIT_MASK; } @@ -1419,7 +1424,7 @@ static unsigned countZeros(const unsigned char* data, size_t size, size_t pos) const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH; if(end > data + size) end = data + size; data = start; - while (data != end && *data == 0) data++; + while(data != end && *data == 0) ++data; /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/ return (unsigned)(data - start); } @@ -1468,12 +1473,12 @@ static unsigned encodeLZ77(uivector* out, Hash* hash, const unsigned char *lastptr, *foreptr, *backptr; unsigned hashpos; - if(windowsize <= 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/ + if(windowsize == 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/ if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/ if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH; - for(pos = inpos; pos < insize; pos++) + for(pos = inpos; pos < insize; ++pos) { size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/ unsigned chainlength = 0; @@ -1482,8 +1487,8 @@ static unsigned encodeLZ77(uivector* out, Hash* hash, if(usezeros && hashval == 0) { - if (numzeros == 0) numzeros = countZeros(in, insize, pos); - else if (pos + numzeros > insize || in[pos + numzeros - 1] != 0) numzeros--; + if(numzeros == 0) numzeros = countZeros(in, insize, pos); + else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; } else { @@ -1542,11 +1547,14 @@ static unsigned encodeLZ77(uivector* out, Hash* hash, } if(hashpos == hash->chain[hashpos]) break; - - if(numzeros >= 3 && length > numzeros) { + + if(numzeros >= 3 && length > numzeros) + { hashpos = hash->chainz[hashpos]; if(hash->zeros[hashpos] != numzeros) break; - } else { + } + else + { hashpos = hash->chain[hashpos]; /*outdated hash value, happens if particular value was not encountered in whole last window*/ if(hash->val[hashpos] != (int)hashval) break; @@ -1577,7 +1585,7 @@ static unsigned encodeLZ77(uivector* out, Hash* hash, offset = lazyoffset; hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/ hash->headz[numzeros] = -1; /*idem*/ - pos--; + --pos; } } } @@ -1597,15 +1605,15 @@ static unsigned encodeLZ77(uivector* out, Hash* hash, else { addLengthDistance(out, length, offset); - for(i = 1; i < length; i++) + for(i = 1; i < length; ++i) { - pos++; + ++pos; wpos = pos & (windowsize - 1); hashval = getHash(in, insize, pos); if(usezeros && hashval == 0) { - if (numzeros == 0) numzeros = countZeros(in, insize, pos); - else if (pos + numzeros > insize || in[pos + numzeros - 1] != 0) numzeros--; + if(numzeros == 0) numzeros = countZeros(in, insize, pos); + else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; } else { @@ -1628,7 +1636,7 @@ static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, s size_t i, j, numdeflateblocks = (datasize + 65534) / 65535; unsigned datapos = 0; - for(i = 0; i < numdeflateblocks; i++) + for(i = 0; i != numdeflateblocks; ++i) { unsigned BFINAL, BTYPE, LEN, NLEN; unsigned char firstbyte; @@ -1649,7 +1657,7 @@ static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, s ucvector_push_back(out, (unsigned char)(NLEN / 256)); /*Decompressed data*/ - for(j = 0; j < 65535 && datapos < datasize; j++) + for(j = 0; j < 65535 && datapos < datasize; ++j) { ucvector_push_back(out, data[datapos++]); } @@ -1667,7 +1675,7 @@ static void writeLZ77data(size_t* bp, ucvector* out, const uivector* lz77_encode const HuffmanTree* tree_ll, const HuffmanTree* tree_d) { size_t i = 0; - for(i = 0; i < lz77_encoded->size; i++) + for(i = 0; i != lz77_encoded->size; ++i) { unsigned val = lz77_encoded->data[i]; addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_ll, val), HuffmanTree_getLength(tree_ll, val)); @@ -1760,21 +1768,21 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, else { if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/); - for(i = datapos; i < dataend; i++) lz77_encoded.data[i] = data[i]; /*no LZ77, but still will be Huffman compressed*/ + for(i = datapos; i < dataend; ++i) lz77_encoded.data[i] = data[i]; /*no LZ77, but still will be Huffman compressed*/ } if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 /*alloc fail*/); if(!uivector_resizev(&frequencies_d, 30, 0)) ERROR_BREAK(83 /*alloc fail*/); /*Count the frequencies of lit, len and dist codes*/ - for(i = 0; i < lz77_encoded.size; i++) + for(i = 0; i != lz77_encoded.size; ++i) { unsigned symbol = lz77_encoded.data[i]; - frequencies_ll.data[symbol]++; + ++frequencies_ll.data[symbol]; if(symbol > 256) { unsigned dist = lz77_encoded.data[i + 2]; - frequencies_d.data[dist]++; + ++frequencies_d.data[dist]; i += 3; } } @@ -1790,19 +1798,19 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, numcodes_ll = tree_ll.numcodes; if(numcodes_ll > 286) numcodes_ll = 286; numcodes_d = tree_d.numcodes; if(numcodes_d > 30) numcodes_d = 30; /*store the code lengths of both generated trees in bitlen_lld*/ - for(i = 0; i < numcodes_ll; i++) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (unsigned)i)); - for(i = 0; i < numcodes_d; i++) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (unsigned)i)); + for(i = 0; i != numcodes_ll; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (unsigned)i)); + for(i = 0; i != numcodes_d; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (unsigned)i)); /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times), 17 (3-10 zeroes), 18 (11-138 zeroes)*/ - for(i = 0; i < (unsigned)bitlen_lld.size; i++) + for(i = 0; i != (unsigned)bitlen_lld.size; ++i) { unsigned j = 0; /*amount of repititions*/ - while(i + j + 1 < (unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) j++; + while(i + j + 1 < (unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) ++j; if(bitlen_lld.data[i] == 0 && j >= 2) /*repeat code for zeroes*/ { - j++; /*include the first zero*/ + ++j; /*include the first zero*/ if(j <= 10) /*repeat code 17 supports max 10 zeroes*/ { uivector_push_back(&bitlen_lld_e, 17); @@ -1821,7 +1829,7 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, size_t k; unsigned num = j / 6, rest = j % 6; uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); - for(k = 0; k < num; k++) + for(k = 0; k < num; ++k) { uivector_push_back(&bitlen_lld_e, 16); uivector_push_back(&bitlen_lld_e, 6 - 3); @@ -1843,12 +1851,12 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, /*generate tree_cl, the huffmantree of huffmantrees*/ if(!uivector_resizev(&frequencies_cl, NUM_CODE_LENGTH_CODES, 0)) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < bitlen_lld_e.size; i++) + for(i = 0; i != bitlen_lld_e.size; ++i) { - frequencies_cl.data[bitlen_lld_e.data[i]]++; + ++frequencies_cl.data[bitlen_lld_e.data[i]]; /*after a repeat code come the bits that specify the number of repetitions, those don't need to be in the frequencies_cl calculation*/ - if(bitlen_lld_e.data[i] >= 16) i++; + if(bitlen_lld_e.data[i] >= 16) ++i; } error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl.data, @@ -1856,7 +1864,7 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, if(error) break; if(!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < tree_cl.numcodes; i++) + for(i = 0; i != tree_cl.numcodes; ++i) { /*lenghts of code length tree is in the order as specified by deflate*/ bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]); @@ -1892,16 +1900,16 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, HDIST = (unsigned)(numcodes_d - 1); HCLEN = (unsigned)bitlen_cl.size - 4; /*trim zeroes for HCLEN. HLIT and HDIST were already trimmed at tree creation*/ - while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) HCLEN--; + while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) --HCLEN; addBitsToStream(bp, out, HLIT, 5); addBitsToStream(bp, out, HDIST, 5); addBitsToStream(bp, out, HCLEN, 4); /*write the code lenghts of the code length alphabet*/ - for(i = 0; i < HCLEN + 4; i++) addBitsToStream(bp, out, bitlen_cl.data[i], 3); + for(i = 0; i != HCLEN + 4; ++i) addBitsToStream(bp, out, bitlen_cl.data[i], 3); /*write the lenghts of the lit/len AND the dist alphabet*/ - for(i = 0; i < bitlen_lld_e.size; i++) + for(i = 0; i != bitlen_lld_e.size; ++i) { addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]), HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i])); @@ -1970,7 +1978,7 @@ static unsigned deflateFixed(ucvector* out, size_t* bp, Hash* hash, } else /*no LZ77, but still will be Huffman compressed*/ { - for(i = datapos; i < dataend; i++) + for(i = datapos; i < dataend; ++i) { addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, data[i]), HuffmanTree_getLength(&tree_ll, data[i])); } @@ -1998,8 +2006,10 @@ static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t else if(settings->btype == 1) blocksize = insize; else /*if(settings->btype == 2)*/ { + /*on PNGs, deflate blocks of 65-262k seem to give most dense encoding*/ blocksize = insize / 8 + 8; - if(blocksize < 65535) blocksize = 65535; + if(blocksize < 65536) blocksize = 65536; + if(blocksize > 262144) blocksize = 262144; } numdeflateblocks = (insize + blocksize - 1) / blocksize; @@ -2008,7 +2018,7 @@ static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t error = hash_init(&hash, settings->windowsize); if(error) return error; - for(i = 0; i < numdeflateblocks && !error; i++) + for(i = 0; i != numdeflateblocks && !error; ++i) { unsigned final = (i == numdeflateblocks - 1); size_t start = i * blocksize; @@ -2071,7 +2081,7 @@ static unsigned update_adler32(unsigned adler, const unsigned char* data, unsign { s1 += (*data++); s2 += s1; - amount--; + --amount; } s1 %= 65521; s2 %= 65521; @@ -2165,7 +2175,6 @@ unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsig unsigned char* deflatedata = 0; size_t deflatesize = 0; - unsigned ADLER32; /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/ unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/ unsigned FLEVEL = 0; @@ -2184,8 +2193,8 @@ unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsig if(!error) { - ADLER32 = adler32(in, (unsigned)insize); - for(i = 0; i < deflatesize; i++) ucvector_push_back(&outv, deflatedata[i]); + unsigned ADLER32 = adler32(in, (unsigned)insize); + for(i = 0; i != deflatesize; ++i) ucvector_push_back(&outv, deflatedata[i]); lodepng_free(deflatedata); lodepng_add32bitInt(&outv, ADLER32); } @@ -2218,7 +2227,7 @@ static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsign static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { - if (!settings->custom_zlib) return 87; /*no custom zlib function provided */ + if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -2226,7 +2235,7 @@ static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsi static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { - if (!settings->custom_zlib) return 87; /*no custom zlib function provided */ + if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_ENCODER*/ @@ -2287,6 +2296,8 @@ const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, /* / CRC32 / */ /* ////////////////////////////////////////////////////////////////////////// */ + +#ifndef LODEPNG_NO_COMPILE_CRC /* CRC polynomial: 0xedb88320 */ static unsigned lodepng_crc32_table[256] = { 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, @@ -2329,12 +2340,13 @@ unsigned lodepng_crc32(const unsigned char* buf, size_t len) unsigned c = 0xffffffffL; size_t n; - for(n = 0; n < len; n++) + for(n = 0; n < len; ++n) { c = lodepng_crc32_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); } return c ^ 0xffffffffL; } +#endif /* !LODEPNG_NO_COMPILE_CRC */ /* ////////////////////////////////////////////////////////////////////////// */ /* / Reading and writing single bits and bytes from/to stream for LodePNG / */ @@ -2343,7 +2355,7 @@ unsigned lodepng_crc32(const unsigned char* buf, size_t len) static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) { unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); - (*bitpointer)++; + ++(*bitpointer); return result; } @@ -2351,7 +2363,7 @@ static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned ch { unsigned result = 0; size_t i; - for(i = nbits - 1; i < nbits; i--) + for(i = nbits - 1; i < nbits; --i) { result += (unsigned)readBitFromReversedStream(bitpointer, bitstream) << i; } @@ -2367,7 +2379,7 @@ static void setBitOfReversedStream0(size_t* bitpointer, unsigned char* bitstream /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/ bitstream[(*bitpointer) >> 3] |= (bit << (7 - ((*bitpointer) & 0x7))); } - (*bitpointer)++; + ++(*bitpointer); } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -2376,7 +2388,7 @@ static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, /*the current bit in bitstream may be 0 or 1 for this to work*/ if(bit == 0) bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7)))); else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7))); - (*bitpointer)++; + ++(*bitpointer); } /* ////////////////////////////////////////////////////////////////////////// */ @@ -2391,7 +2403,7 @@ unsigned lodepng_chunk_length(const unsigned char* chunk) void lodepng_chunk_type(char type[5], const unsigned char* chunk) { unsigned i; - for(i = 0; i < 4; i++) type[i] = (char)chunk[4 + i]; + for(i = 0; i != 4; ++i) type[i] = (char)chunk[4 + i]; type[4] = 0; /*null termination char*/ } @@ -2469,7 +2481,7 @@ unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsi (*outlength) = new_length; chunk_start = &(*out)[new_length - total_chunk_length]; - for(i = 0; i < total_chunk_length; i++) chunk_start[i] = chunk[i]; + for(i = 0; i != total_chunk_length; ++i) chunk_start[i] = chunk[i]; return 0; } @@ -2497,7 +2509,7 @@ unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned l chunk[7] = (unsigned char)type[3]; /*3: the data*/ - for(i = 0; i < length; i++) chunk[8 + i] = data[i]; + for(i = 0; i != length; ++i) chunk[8 + i] = data[i]; /*4: CRC (of the chunkname characters and the data)*/ lodepng_chunk_generate_crc(chunk); @@ -2569,7 +2581,7 @@ unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* { dest->palette = (unsigned char*)lodepng_malloc(1024); if(!dest->palette && source->palettesize) return 83; /*alloc fail*/ - for(i = 0; i < source->palettesize * 4; i++) dest->palette[i] = source->palette[i]; + for(i = 0; i != source->palettesize * 4; ++i) dest->palette[i] = source->palette[i]; } return 0; } @@ -2587,7 +2599,7 @@ static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColo if(a->key_b != b->key_b) return 0; } if(a->palettesize != b->palettesize) return 0; - for(i = 0; i < a->palettesize * 4; i++) + for(i = 0; i != a->palettesize * 4; ++i) { if(a->palette[i] != b->palette[i]) return 0; } @@ -2618,7 +2630,7 @@ unsigned lodepng_palette_add(LodePNGColorMode* info, info->palette[4 * info->palettesize + 1] = g; info->palette[4 * info->palettesize + 2] = b; info->palette[4 * info->palettesize + 3] = a; - info->palettesize++; + ++info->palettesize; return 0; } @@ -2651,7 +2663,7 @@ unsigned lodepng_is_palette_type(const LodePNGColorMode* info) unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info) { size_t i; - for(i = 0; i < info->palettesize; i++) + for(i = 0; i != info->palettesize; ++i) { if(info->palette[i * 4 + 3] < 255) return 1; } @@ -2691,14 +2703,14 @@ static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, const LodePNGCol static void LodePNGUnknownChunks_init(LodePNGInfo* info) { unsigned i; - for(i = 0; i < 3; i++) info->unknown_chunks_data[i] = 0; - for(i = 0; i < 3; i++) info->unknown_chunks_size[i] = 0; + for(i = 0; i != 3; ++i) info->unknown_chunks_data[i] = 0; + for(i = 0; i != 3; ++i) info->unknown_chunks_size[i] = 0; } static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info) { unsigned i; - for(i = 0; i < 3; i++) lodepng_free(info->unknown_chunks_data[i]); + for(i = 0; i != 3; ++i) lodepng_free(info->unknown_chunks_data[i]); } static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* src) @@ -2707,13 +2719,13 @@ static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* LodePNGUnknownChunks_cleanup(dest); - for(i = 0; i < 3; i++) + for(i = 0; i != 3; ++i) { size_t j; dest->unknown_chunks_size[i] = src->unknown_chunks_size[i]; dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]); if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/ - for(j = 0; j < src->unknown_chunks_size[i]; j++) + for(j = 0; j < src->unknown_chunks_size[i]; ++j) { dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j]; } @@ -2734,7 +2746,7 @@ static void LodePNGText_init(LodePNGInfo* info) static void LodePNGText_cleanup(LodePNGInfo* info) { size_t i; - for(i = 0; i < info->text_num; i++) + for(i = 0; i != info->text_num; ++i) { string_cleanup(&info->text_keys[i]); string_cleanup(&info->text_strings[i]); @@ -2749,7 +2761,7 @@ static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source) dest->text_keys = 0; dest->text_strings = 0; dest->text_num = 0; - for(i = 0; i < source->text_num; i++) + for(i = 0; i != source->text_num; ++i) { CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i])); } @@ -2772,7 +2784,7 @@ unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str) return 83; /*alloc fail*/ } - info->text_num++; + ++info->text_num; info->text_keys = new_keys; info->text_strings = new_strings; @@ -2799,7 +2811,7 @@ static void LodePNGIText_init(LodePNGInfo* info) static void LodePNGIText_cleanup(LodePNGInfo* info) { size_t i; - for(i = 0; i < info->itext_num; i++) + for(i = 0; i != info->itext_num; ++i) { string_cleanup(&info->itext_keys[i]); string_cleanup(&info->itext_langtags[i]); @@ -2820,7 +2832,7 @@ static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) dest->itext_transkeys = 0; dest->itext_strings = 0; dest->itext_num = 0; - for(i = 0; i < source->itext_num; i++) + for(i = 0; i != source->itext_num; ++i) { CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i], source->itext_transkeys[i], source->itext_strings[i])); @@ -2849,7 +2861,7 @@ unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langt return 83; /*alloc fail*/ } - info->itext_num++; + ++info->itext_num; info->itext_keys = new_keys; info->itext_langtags = new_langtags; info->itext_transkeys = new_transkeys; @@ -2957,14 +2969,14 @@ struct ColorTree static void color_tree_init(ColorTree* tree) { int i; - for(i = 0; i < 16; i++) tree->children[i] = 0; + for(i = 0; i != 16; ++i) tree->children[i] = 0; tree->index = -1; } static void color_tree_cleanup(ColorTree* tree) { int i; - for(i = 0; i < 16; i++) + for(i = 0; i != 16; ++i) { if(tree->children[i]) { @@ -2978,7 +2990,7 @@ static void color_tree_cleanup(ColorTree* tree) static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { int bit = 0; - for(bit = 0; bit < 8; bit++) + for(bit = 0; bit < 8; ++bit) { int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); if(!tree->children[i]) return -1; @@ -3000,7 +3012,7 @@ static void color_tree_add(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) { int bit; - for(bit = 0; bit < 8; bit++) + for(bit = 0; bit < 8; ++bit) { int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); if(!tree->children[i]) @@ -3249,7 +3261,7 @@ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, { if(mode->bitdepth == 8) { - for(i = 0; i < numpixels; i++, buffer += num_channels) + for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i]; if(has_alpha) buffer[3] = mode->key_defined && in[i] == mode->key_r ? 0 : 255; @@ -3257,7 +3269,7 @@ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, } else if(mode->bitdepth == 16) { - for(i = 0; i < numpixels; i++, buffer += num_channels) + for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 2]; if(has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255; @@ -3267,7 +3279,7 @@ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, { unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ size_t j = 0; - for(i = 0; i < numpixels; i++, buffer += num_channels) + for(i = 0; i != numpixels; ++i, buffer += num_channels) { unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; @@ -3279,7 +3291,7 @@ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, { if(mode->bitdepth == 8) { - for(i = 0; i < numpixels; i++, buffer += num_channels) + for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 3 + 0]; buffer[1] = in[i * 3 + 1]; @@ -3290,7 +3302,7 @@ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, } else { - for(i = 0; i < numpixels; i++, buffer += num_channels) + for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 6 + 0]; buffer[1] = in[i * 6 + 2]; @@ -3306,7 +3318,7 @@ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, { unsigned index; size_t j = 0; - for(i = 0; i < numpixels; i++, buffer += num_channels) + for(i = 0; i != numpixels; ++i, buffer += num_channels) { if(mode->bitdepth == 8) index = in[i]; else index = readBitsFromReversedStream(&j, in, mode->bitdepth); @@ -3331,7 +3343,7 @@ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, { if(mode->bitdepth == 8) { - for(i = 0; i < numpixels; i++, buffer += num_channels) + for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; if(has_alpha) buffer[3] = in[i * 2 + 1]; @@ -3339,7 +3351,7 @@ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, } else { - for(i = 0; i < numpixels; i++, buffer += num_channels) + for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; if(has_alpha) buffer[3] = in[i * 4 + 2]; @@ -3350,7 +3362,7 @@ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, { if(mode->bitdepth == 8) { - for(i = 0; i < numpixels; i++, buffer += num_channels) + for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 4 + 0]; buffer[1] = in[i * 4 + 1]; @@ -3360,7 +3372,7 @@ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, } else { - for(i = 0; i < numpixels; i++, buffer += num_channels) + for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 8 + 0]; buffer[1] = in[i * 8 + 2]; @@ -3417,7 +3429,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, if(lodepng_color_mode_equal(mode_out, mode_in)) { size_t numbytes = lodepng_get_raw_size(w, h, mode_in); - for(i = 0; i < numbytes; i++) out[i] = in[i]; + for(i = 0; i != numbytes; ++i) out[i] = in[i]; return 0; } @@ -3426,7 +3438,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, size_t palsize = 1u << mode_out->bitdepth; if(mode_out->palettesize < palsize) palsize = mode_out->palettesize; color_tree_init(&tree); - for(i = 0; i < palsize; i++) + for(i = 0; i != palsize; ++i) { unsigned char* p = &mode_out->palette[i * 4]; color_tree_add(&tree, p[0], p[1], p[2], p[3], i); @@ -3435,7 +3447,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) { - for(i = 0; i < numpixels; i++) + for(i = 0; i != numpixels; ++i) { unsigned short r = 0, g = 0, b = 0, a = 0; getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); @@ -3453,7 +3465,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, else { unsigned char r = 0, g = 0, b = 0, a = 0; - for(i = 0; i < numpixels; i++) + for(i = 0; i != numpixels; ++i) { getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); @@ -3494,7 +3506,7 @@ void lodepng_color_profile_init(LodePNGColorProfile* profile) }*/ /*Returns how many bits needed to represent given value (max 8 bit)*/ -unsigned getValueRequiredBits(unsigned char value) +static unsigned getValueRequiredBits(unsigned char value) { if(value == 0 || value == 255) return 1; /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/ @@ -3504,9 +3516,9 @@ unsigned getValueRequiredBits(unsigned char value) /*profile must already have been inited with mode. It's ok to set some parameters of profile to done already.*/ -unsigned get_color_profile(LodePNGColorProfile* profile, - const unsigned char* in, unsigned w, unsigned h, - const LodePNGColorMode* mode) +unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, + const unsigned char* in, unsigned w, unsigned h, + const LodePNGColorMode* mode) { unsigned error = 0; size_t i; @@ -3528,10 +3540,11 @@ unsigned get_color_profile(LodePNGColorProfile* profile, if(mode->bitdepth == 16) { unsigned short r, g, b, a; - for(i = 0; i < numpixels; i++) + for(i = 0; i != numpixels; ++i) { getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); - if(r % 257u != 0 || g % 257u != 0 || b % 257u != 0 || a % 257u != 0) /*first and second byte differ*/ + if((r & 255) != ((r >> 8) & 255) || (g & 255) != ((g >> 8) & 255) || + (b & 255) != ((b >> 8) & 255) || (a & 255) != ((a >> 8) & 255)) /*first and second byte differ*/ { sixteen = 1; break; @@ -3545,10 +3558,10 @@ unsigned get_color_profile(LodePNGColorProfile* profile, profile->bits = 16; bits_done = numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/ - for(i = 0; i < numpixels; i++) + for(i = 0; i != numpixels; ++i) { getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); - + if(!colored_done && (r != g || r != b)) { profile->colored = 1; @@ -3584,7 +3597,7 @@ unsigned get_color_profile(LodePNGColorProfile* profile, } else /* < 16-bit */ { - for(i = 0; i < numpixels; i++) + for(i = 0; i != numpixels; ++i) { unsigned char r = 0, g = 0, b = 0, a = 0; getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode); @@ -3643,7 +3656,7 @@ unsigned get_color_profile(LodePNGColorProfile* profile, p[n * 4 + 2] = b; p[n * 4 + 3] = a; } - profile->numcolors++; + ++profile->numcolors; numcolors_done = profile->numcolors >= maxnumcolors; } } @@ -3652,9 +3665,9 @@ unsigned get_color_profile(LodePNGColorProfile* profile, } /*make the profile's key always 16-bit for consistency - repeat each byte twice*/ - profile->key_r *= 257; - profile->key_g *= 257; - profile->key_b *= 257; + profile->key_r += (profile->key_r << 8); + profile->key_g += (profile->key_g << 8); + profile->key_b += (profile->key_b << 8); } color_tree_cleanup(&tree); @@ -3675,11 +3688,15 @@ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, unsigned i, n, palettebits, grey_ok, palette_ok; lodepng_color_profile_init(&prof); - error = get_color_profile(&prof, image, w, h, mode_in); + error = lodepng_get_color_profile(&prof, image, w, h, mode_in); if(error) return error; mode_out->key_defined = 0; - if(prof.key && w * h <= 16) prof.alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ + if(prof.key && w * h <= 16) + { + prof.alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ + if(prof.bits < 8) prof.bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } grey_ok = !prof.colored && !prof.alpha; /*grey without alpha, with potentially low bits*/ n = prof.numcolors; palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); @@ -3691,7 +3708,7 @@ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, { unsigned char* p = prof.palette; lodepng_palette_clear(mode_out); /*remove potential earlier palette*/ - for(i = 0; i < prof.numcolors; i++) + for(i = 0; i != prof.numcolors; ++i) { error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]); if(error) break; @@ -3774,7 +3791,7 @@ static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t fil unsigned i; /*calculate width and height in pixels of each pass*/ - for(i = 0; i < 7; i++) + for(i = 0; i != 7; ++i) { passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; @@ -3783,7 +3800,7 @@ static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t fil } filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; - for(i = 0; i < 7; i++) + for(i = 0; i != 7; ++i) { /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/ filter_passstart[i + 1] = filter_passstart[i] @@ -3810,7 +3827,7 @@ unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, { CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/ } - if(insize < 29) + if(insize < 33) { CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/ } @@ -3838,6 +3855,11 @@ unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, info->filter_method = in[27]; info->interlace_method = in[28]; + if(*w == 0 || *h == 0) + { + CERROR_RETURN_ERROR(state->error, 93); + } + if(!state->decoder.ignore_crc) { unsigned CRC = lodepng_read32bitInt(&in[29]); @@ -3875,53 +3897,53 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan switch(filterType) { case 0: - for(i = 0; i < length; i++) recon[i] = scanline[i]; + for(i = 0; i != length; ++i) recon[i] = scanline[i]; break; case 1: - for(i = 0; i < bytewidth; i++) recon[i] = scanline[i]; - for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth]; + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth]; break; case 2: if(precon) { - for(i = 0; i < length; i++) recon[i] = scanline[i] + precon[i]; + for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i]; } else { - for(i = 0; i < length; i++) recon[i] = scanline[i]; + for(i = 0; i != length; ++i) recon[i] = scanline[i]; } break; case 3: if(precon) { - for(i = 0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2; - for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2); + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + precon[i] / 2; + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2); } else { - for(i = 0; i < bytewidth; i++) recon[i] = scanline[i]; - for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2; + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth] / 2; } break; case 4: if(precon) { - for(i = 0; i < bytewidth; i++) + for(i = 0; i != bytewidth; ++i) { recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ } - for(i = bytewidth; i < length; i++) + for(i = bytewidth; i < length; ++i) { recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); } } else { - for(i = 0; i < bytewidth; i++) + for(i = 0; i != bytewidth; ++i) { recon[i] = scanline[i]; } - for(i = bytewidth; i < length; i++) + for(i = bytewidth; i < length; ++i) { /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/ recon[i] = (scanline[i] + recon[i - bytewidth]); @@ -3950,7 +3972,7 @@ static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w size_t bytewidth = (bpp + 7) / 8; size_t linebytes = (w * bpp + 7) / 8; - for(y = 0; y < h; y++) + for(y = 0; y < h; ++y) { size_t outindex = linebytes * y; size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ @@ -3985,16 +4007,16 @@ static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsig if(bpp >= 8) { - for(i = 0; i < 7; i++) + for(i = 0; i != 7; ++i) { unsigned x, y, b; size_t bytewidth = bpp / 8; - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth; size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; - for(b = 0; b < bytewidth; b++) + for(b = 0; b < bytewidth; ++b) { out[pixeloutstart + b] = in[pixelinstart + b]; } @@ -4003,18 +4025,18 @@ static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsig } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ { - for(i = 0; i < 7; i++) + for(i = 0; i != 7; ++i) { unsigned x, y, b; unsigned ilinebits = bpp * passw[i]; unsigned olinebits = bpp * w; size_t obp, ibp; /*bit pointers (for out and in buffer)*/ - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp); obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; - for(b = 0; b < bpp; b++) + for(b = 0; b < bpp; ++b) { unsigned char bit = readBitFromReversedStream(&ibp, in); /*note that this function assumes the out buffer is completely 0, use setBitOfReversedStream otherwise*/ @@ -4040,10 +4062,10 @@ static void removePaddingBits(unsigned char* out, const unsigned char* in, unsigned y; size_t diff = ilinebits - olinebits; size_t ibp = 0, obp = 0; /*input and output bit pointers*/ - for(y = 0; y < h; y++) + for(y = 0; y < h; ++y) { size_t x; - for(x = 0; x < olinebits; x++) + for(x = 0; x < olinebits; ++x) { unsigned char bit = readBitFromReversedStream(&ibp, in); setBitOfReversedStream(&obp, out, bit); @@ -4085,7 +4107,7 @@ static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - for(i = 0; i < 7; i++) + for(i = 0; i != 7; ++i) { CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp)); /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, @@ -4118,7 +4140,7 @@ static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* dat } if(color->palettesize > 256) return 38; /*error: palette too big*/ - for(i = 0; i < color->palettesize; i++) + for(i = 0; i != color->palettesize; ++i) { color->palette[4 * i + 0] = data[pos++]; /*R*/ color->palette[4 * i + 1] = data[pos++]; /*G*/ @@ -4137,7 +4159,7 @@ static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* dat /*error: more alpha values given than there are palette entries*/ if(chunkLength > color->palettesize) return 38; - for(i = 0; i < chunkLength; i++) color->palette[4 * i + 3] = data[i]; + for(i = 0; i != chunkLength; ++i) color->palette[4 * i + 3] = data[i]; } else if(color->colortype == LCT_GREY) { @@ -4209,7 +4231,7 @@ static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, siz unsigned length, string2_begin; length = 0; - while(length < chunkLength && data[length] != 0) length++; + while(length < chunkLength && data[length] != 0) ++length; /*even though it's not allowed by the standard, no error is thrown if there's no null termination char, if the text is empty*/ if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ @@ -4218,7 +4240,7 @@ static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, siz if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ key[length] = 0; - for(i = 0; i < length; i++) key[i] = (char)data[i]; + for(i = 0; i != length; ++i) key[i] = (char)data[i]; string2_begin = length + 1; /*skip keyword null terminator*/ @@ -4227,7 +4249,7 @@ static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, siz if(!str) CERROR_BREAK(error, 83); /*alloc fail*/ str[length] = 0; - for(i = 0; i < length; i++) str[i] = (char)data[string2_begin + i]; + for(i = 0; i != length; ++i) str[i] = (char)data[string2_begin + i]; error = lodepng_add_text(info, key, str); @@ -4255,7 +4277,7 @@ static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSetting while(!error) /*not really a while loop, only used to break on error*/ { - for(length = 0; length < chunkLength && data[length] != 0; length++) ; + for(length = 0; length < chunkLength && data[length] != 0; ++length) ; if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ @@ -4263,7 +4285,7 @@ static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSetting if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ key[length] = 0; - for(i = 0; i < length; i++) key[i] = (char)data[i]; + for(i = 0; i != length; ++i) key[i] = (char)data[i]; if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ @@ -4308,7 +4330,7 @@ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSetting if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/ /*read the key*/ - for(length = 0; length < chunkLength && data[length] != 0; length++) ; + for(length = 0; length < chunkLength && data[length] != 0; ++length) ; if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/ if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ @@ -4316,7 +4338,7 @@ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSetting if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ key[length] = 0; - for(i = 0; i < length; i++) key[i] = (char)data[i]; + for(i = 0; i != length; ++i) key[i] = (char)data[i]; /*read the compression method*/ compressed = data[length + 1]; @@ -4328,24 +4350,24 @@ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSetting /*read the langtag*/ begin = length + 3; length = 0; - for(i = begin; i < chunkLength && data[i] != 0; i++) length++; + for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; langtag = (char*)lodepng_malloc(length + 1); if(!langtag) CERROR_BREAK(error, 83); /*alloc fail*/ langtag[length] = 0; - for(i = 0; i < length; i++) langtag[i] = (char)data[begin + i]; + for(i = 0; i != length; ++i) langtag[i] = (char)data[begin + i]; /*read the transkey*/ begin += length + 1; length = 0; - for(i = begin; i < chunkLength && data[i] != 0; i++) length++; + for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; transkey = (char*)lodepng_malloc(length + 1); if(!transkey) CERROR_BREAK(error, 83); /*alloc fail*/ transkey[length] = 0; - for(i = 0; i < length; i++) transkey[i] = (char)data[begin + i]; + for(i = 0; i != length; ++i) transkey[i] = (char)data[begin + i]; /*read the actual text*/ begin += length + 1; @@ -4367,7 +4389,7 @@ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSetting if(!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 /*alloc fail*/); decoded.data[length] = 0; - for(i = 0; i < length; i++) decoded.data[i] = data[begin + i]; + for(i = 0; i != length; ++i) decoded.data[i] = data[begin + i]; } error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data); @@ -4422,6 +4444,7 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, ucvector idat; /*the data from idat chunks*/ ucvector scanlines; size_t predict; + size_t numpixels; /*for unknown chunk order*/ unsigned unknown = 0; @@ -4435,6 +4458,14 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ if(state->error) return; + numpixels = *w * *h; + + /*multiplication overflow*/ + if(*h != 0 && numpixels / *h != *w) CERROR_RETURN(state->error, 92); + /*multiplication overflow possible further below. Allows up to 2^31-1 pixel + bytes with 16-bit RGBA, the rest is room for filter bytes.*/ + if(numpixels > 268435455) CERROR_RETURN(state->error, 92); + ucvector_init(&idat); chunk = &in[33]; /*first byte of the first chunk after the header*/ @@ -4465,7 +4496,7 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, { size_t oldsize = idat.size; if(!ucvector_resize(&idat, oldsize + chunkLength)) CERROR_BREAK(state->error, 83 /*alloc fail*/); - for(i = 0; i < chunkLength; i++) idat.data[oldsize + i] = data[i]; + for(i = 0; i != chunkLength; ++i) idat.data[oldsize + i] = data[i]; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS critical_pos = 3; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ @@ -4561,22 +4592,40 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, ucvector_init(&scanlines); /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation. - The prediction is currently not correct for interlaced PNG images.*/ - predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color) + *h; + If the decompressed size does not match the prediction, the image must be corrupt.*/ + if(state->info_png.interlace_method == 0) + { + /*The extra *h is added because this are the filter bytes every scanline starts with*/ + predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color) + *h; + } + else + { + /*Adam-7 interlaced: predicted size is the sum of the 7 sub-images sizes*/ + const LodePNGColorMode* color = &state->info_png.color; + predict = 0; + predict += lodepng_get_raw_size_idat((*w + 7) / 8, (*h + 7) / 8, color) + (*h + 7) / 8; + if(*w > 4) predict += lodepng_get_raw_size_idat((*w + 3) / 8, (*h + 7) / 8, color) + (*h + 7) / 8; + predict += lodepng_get_raw_size_idat((*w + 3) / 4, (*h + 3) / 8, color) + (*h + 3) / 8; + if(*w > 2) predict += lodepng_get_raw_size_idat((*w + 1) / 4, (*h + 3) / 4, color) + (*h + 3) / 4; + predict += lodepng_get_raw_size_idat((*w + 1) / 2, (*h + 1) / 4, color) + (*h + 1) / 4; + if(*w > 1) predict += lodepng_get_raw_size_idat((*w + 0) / 2, (*h + 1) / 2, color) + (*h + 1) / 2; + predict += lodepng_get_raw_size_idat((*w + 0) / 1, (*h + 0) / 2, color) + (*h + 0) / 2; + } if(!state->error && !ucvector_reserve(&scanlines, predict)) state->error = 83; /*alloc fail*/ if(!state->error) { state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data, idat.size, &state->decoder.zlibsettings); + if(!state->error && scanlines.size != predict) state->error = 91; /*decompressed size doesn't match prediction*/ } ucvector_cleanup(&idat); if(!state->error) { + size_t outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color); ucvector outv; ucvector_init(&outv); - if(!ucvector_resizev(&outv, - lodepng_get_raw_size(*w, *h, &state->info_png.color), 0)) state->error = 83; /*alloc fail*/ + if(!ucvector_resizev(&outv, outsize, 0)) state->error = 83; /*alloc fail*/ if(!state->error) state->error = postProcessScanlines(outv.data, scanlines.data, *w, *h, &state->info_png); *out = outv.data; } @@ -4775,7 +4824,7 @@ static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info) size_t i; ucvector PLTE; ucvector_init(&PLTE); - for(i = 0; i < info->palettesize * 4; i++) + for(i = 0; i != info->palettesize * 4; ++i) { /*add all channels except alpha channel*/ if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); @@ -4796,13 +4845,13 @@ static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info) { size_t amount = info->palettesize; /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/ - for(i = info->palettesize; i > 0; i--) + for(i = info->palettesize; i != 0; --i) { - if(info->palette[4 * (i - 1) + 3] == 255) amount--; + if(info->palette[4 * (i - 1) + 3] == 255) --amount; else break; } /*add only alpha channel*/ - for(i = 0; i < amount; i++) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); + for(i = 0; i != amount; ++i) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); } else if(info->colortype == LCT_GREY) { @@ -4861,10 +4910,10 @@ static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* te size_t i; ucvector text; ucvector_init(&text); - for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&text, (unsigned char)keyword[i]); + for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&text, (unsigned char)keyword[i]); if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ ucvector_push_back(&text, 0); /*0 termination char*/ - for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&text, (unsigned char)textstring[i]); + for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&text, (unsigned char)textstring[i]); error = addChunk(out, "tEXt", text.data, text.size); ucvector_cleanup(&text); @@ -4880,7 +4929,7 @@ static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* te ucvector_init(&data); ucvector_init(&compressed); - for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]); + for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)keyword[i]); if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ ucvector_push_back(&data, 0); /*0 termination char*/ ucvector_push_back(&data, 0); /*compression method: 0*/ @@ -4889,7 +4938,7 @@ static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* te (unsigned char*)textstring, textsize, zlibsettings); if(!error) { - for(i = 0; i < compressed.size; i++) ucvector_push_back(&data, compressed.data[i]); + for(i = 0; i != compressed.size; ++i) ucvector_push_back(&data, compressed.data[i]); error = addChunk(out, "zTXt", data.data, data.size); } @@ -4907,14 +4956,14 @@ static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* ke ucvector_init(&data); - for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]); + for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)keyword[i]); if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ ucvector_push_back(&data, 0); /*null termination char*/ ucvector_push_back(&data, compressed ? 1 : 0); /*compression flag*/ ucvector_push_back(&data, 0); /*compression method*/ - for(i = 0; langtag[i] != 0; i++) ucvector_push_back(&data, (unsigned char)langtag[i]); + for(i = 0; langtag[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)langtag[i]); ucvector_push_back(&data, 0); /*null termination char*/ - for(i = 0; transkey[i] != 0; i++) ucvector_push_back(&data, (unsigned char)transkey[i]); + for(i = 0; transkey[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)transkey[i]); ucvector_push_back(&data, 0); /*null termination char*/ if(compressed) @@ -4925,13 +4974,13 @@ static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* ke (unsigned char*)textstring, textsize, zlibsettings); if(!error) { - for(i = 0; i < compressed_data.size; i++) ucvector_push_back(&data, compressed_data.data[i]); + for(i = 0; i != compressed_data.size; ++i) ucvector_push_back(&data, compressed_data.data[i]); } ucvector_cleanup(&compressed_data); } else /*not compressed*/ { - for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&data, (unsigned char)textstring[i]); + for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)textstring[i]); } if(!error) error = addChunk(out, "iTXt", data.data, data.size); @@ -5011,57 +5060,49 @@ static void filterScanline(unsigned char* out, const unsigned char* scanline, co switch(filterType) { case 0: /*None*/ - for(i = 0; i < length; i++) out[i] = scanline[i]; + for(i = 0; i != length; ++i) out[i] = scanline[i]; break; case 1: /*Sub*/ - if(prevline) - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth]; - } - else - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth]; - } + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth]; break; case 2: /*Up*/ if(prevline) { - for(i = 0; i < length; i++) out[i] = scanline[i] - prevline[i]; + for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i]; } else { - for(i = 0; i < length; i++) out[i] = scanline[i]; + for(i = 0; i != length; ++i) out[i] = scanline[i]; } break; case 3: /*Average*/ if(prevline) { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i] - prevline[i] / 2; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2); + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - prevline[i] / 2; + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2); } else { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth] / 2; + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth] / 2; } break; case 4: /*Paeth*/ if(prevline) { /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/ - for(i = 0; i < bytewidth; i++) out[i] = (scanline[i] - prevline[i]); - for(i = bytewidth; i < length; i++) + for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]); + for(i = bytewidth; i < length; ++i) { out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); } } else { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/ - for(i = bytewidth; i < length; i++) out[i] = (scanline[i] - scanline[i - bytewidth]); + for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]); } break; default: return; /*unexisting filter type given*/ @@ -5073,7 +5114,7 @@ static float flog2(float f) { float result = 0; while(f > 32) { result += 4; f /= 16; } - while(f > 2) { result++; f /= 2; } + while(f > 2) { ++result; f /= 2; } return result + 1.442695f * (f * f * f / 3 - 3 * f * f / 2 + 3 * f - 1.83333f); } @@ -5116,7 +5157,7 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, if(strategy == LFS_ZERO) { - for(y = 0; y < h; y++) + for(y = 0; y != h; ++y) { size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ size_t inindex = linebytes * y; @@ -5133,7 +5174,7 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, size_t smallest = 0; unsigned char type, bestType = 0; - for(type = 0; type < 5; type++) + for(type = 0; type != 5; ++type) { ucvector_init(&attempt[type]); if(!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ @@ -5141,10 +5182,10 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, if(!error) { - for(y = 0; y < h; y++) + for(y = 0; y != h; ++y) { /*try the 5 filter types*/ - for(type = 0; type < 5; type++) + for(type = 0; type != 5; ++type) { filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); @@ -5152,11 +5193,11 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, sum[type] = 0; if(type == 0) { - for(x = 0; x < linebytes; x++) sum[type] += (unsigned char)(attempt[type].data[x]); + for(x = 0; x != linebytes; ++x) sum[type] += (unsigned char)(attempt[type].data[x]); } else { - for(x = 0; x < linebytes; x++) + for(x = 0; x != linebytes; ++x) { /*For differences, each byte should be treated as signed, values above 127 are negative (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there. @@ -5178,11 +5219,11 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, /*now fill the out values*/ out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; } } - for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); + for(type = 0; type != 5; ++type) ucvector_cleanup(&attempt[type]); } else if(strategy == LFS_ENTROPY) { @@ -5192,23 +5233,23 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned type, bestType = 0; unsigned count[256]; - for(type = 0; type < 5; type++) + for(type = 0; type != 5; ++type) { ucvector_init(&attempt[type]); if(!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ } - for(y = 0; y < h; y++) + for(y = 0; y != h; ++y) { /*try the 5 filter types*/ - for(type = 0; type < 5; type++) + for(type = 0; type != 5; ++type) { filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); - for(x = 0; x < 256; x++) count[x] = 0; - for(x = 0; x < linebytes; x++) count[attempt[type].data[x]]++; - count[type]++; /*the filter type itself is part of the scanline*/ + for(x = 0; x != 256; ++x) count[x] = 0; + for(x = 0; x != linebytes; ++x) ++count[attempt[type].data[x]]; + ++count[type]; /*the filter type itself is part of the scanline*/ sum[type] = 0; - for(x = 0; x < 256; x++) + for(x = 0; x != 256; ++x) { float p = count[x] / (float)(linebytes + 1); sum[type] += count[x] == 0 ? 0 : flog2(1 / p) * p; @@ -5225,14 +5266,14 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, /*now fill the out values*/ out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; } - for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); + for(type = 0; type != 5; ++type) ucvector_cleanup(&attempt[type]); } else if(strategy == LFS_PREDEFINED) { - for(y = 0; y < h; y++) + for(y = 0; y != h; ++y) { size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ size_t inindex = linebytes * y; @@ -5262,14 +5303,14 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, images only, so disable it*/ zlibsettings.custom_zlib = 0; zlibsettings.custom_deflate = 0; - for(type = 0; type < 5; type++) + for(type = 0; type != 5; ++type) { ucvector_init(&attempt[type]); ucvector_resize(&attempt[type], linebytes); /*todo: give error if resize failed*/ } - for(y = 0; y < h; y++) /*try the 5 filter types*/ + for(y = 0; y != h; ++y) /*try the 5 filter types*/ { - for(type = 0; type < 5; type++) + for(type = 0; type != 5; ++type) { unsigned testsize = attempt[type].size; /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/ @@ -5288,9 +5329,9 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, } prevline = &in[y * linebytes]; out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; } - for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); + for(type = 0; type != 5; ++type) ucvector_cleanup(&attempt[type]); } else return 88; /* unknown filter strategy */ @@ -5305,17 +5346,17 @@ static void addPaddingBits(unsigned char* out, const unsigned char* in, unsigned y; size_t diff = olinebits - ilinebits; size_t obp = 0, ibp = 0; /*bit pointers*/ - for(y = 0; y < h; y++) + for(y = 0; y != h; ++y) { size_t x; - for(x = 0; x < ilinebits; x++) + for(x = 0; x < ilinebits; ++x) { unsigned char bit = readBitFromReversedStream(&ibp, in); setBitOfReversedStream(&obp, out, bit); } /*obp += diff; --> no, fill in some value in the padding bits too, to avoid "Use of uninitialised value of size ###" warning from valgrind*/ - for(x = 0; x < diff; x++) setBitOfReversedStream(&obp, out, 0); + for(x = 0; x != diff; ++x) setBitOfReversedStream(&obp, out, 0); } } @@ -5340,16 +5381,16 @@ static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigne if(bpp >= 8) { - for(i = 0; i < 7; i++) + for(i = 0; i != 7; ++i) { unsigned x, y, b; size_t bytewidth = bpp / 8; - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; - for(b = 0; b < bytewidth; b++) + for(b = 0; b < bytewidth; ++b) { out[pixeloutstart + b] = in[pixelinstart + b]; } @@ -5358,18 +5399,18 @@ static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigne } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ { - for(i = 0; i < 7; i++) + for(i = 0; i != 7; ++i) { unsigned x, y, b; unsigned ilinebits = bpp * passw[i]; unsigned olinebits = bpp * w; size_t obp, ibp; /*bit pointers (for out and in buffer)*/ - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); - for(b = 0; b < bpp; b++) + for(b = 0; b < bpp; ++b) { unsigned char bit = readBitFromReversedStream(&ibp, in); setBitOfReversedStream(&obp, out, bit); @@ -5440,7 +5481,7 @@ static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned i; Adam7_interlace(adam7, in, w, h, bpp); - for(i = 0; i < 7; i++) + for(i = 0; i != 7; ++i) { if(bpp < 8) { @@ -5479,7 +5520,7 @@ static unsigned getPaletteTranslucency(const unsigned char* palette, size_t pale size_t i; unsigned key = 0; unsigned r = 0, g = 0, b = 0; /*the value of the color with alpha 0, so long as color keying is possible*/ - for(i = 0; i < palettesize; i++) + for(i = 0; i != palettesize; ++i) { if(!key && palette[4 * i + 3] == 0) { @@ -5624,7 +5665,7 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize, /*tIME*/ if(info.time_defined) addChunk_tIME(&outv, &info.time); /*tEXt and/or zTXt*/ - for(i = 0; i < info.text_num; i++) + for(i = 0; i != info.text_num; ++i) { if(strlen(info.text_keys[i]) > 79) { @@ -5649,7 +5690,7 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize, if(state->encoder.add_id) { unsigned alread_added_id_text = 0; - for(i = 0; i < info.text_num; i++) + for(i = 0; i != info.text_num; ++i) { if(!strcmp(info.text_keys[i], "LodePNG")) { @@ -5659,11 +5700,11 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize, } if(alread_added_id_text == 0) { - addChunk_tEXt(&outv, "LodePNG", VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/ + addChunk_tEXt(&outv, "LodePNG", LODEPNG_VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/ } } /*iTXt*/ - for(i = 0; i < info.itext_num; i++) + for(i = 0; i != info.itext_num; ++i) { if(strlen(info.itext_keys[i]) > 79) { @@ -5866,6 +5907,9 @@ const char* lodepng_error_text(unsigned code) case 89: return "text chunk keyword too short or long: must have size 1-79"; /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/ case 90: return "windowsize must be a power of two"; + case 91: return "invalid decompressed idat size"; + case 92: return "too many pixels, not supported"; + case 93: return "zero width or height is invalid"; } return "unknown error code"; } @@ -5897,12 +5941,14 @@ void load_file(std::vector& buffer, const std::string& filename) } /*write given buffer to the file, overwriting the file, it doesn't append to it.*/ -void save_file(const std::vector& buffer, const std::string& filename) +unsigned save_file(const std::vector& buffer, const std::string& filename) { std::ofstream file(filename.c_str(), std::ios::out|std::ios::binary); + if(!file) return 79; file.write(buffer.empty() ? 0 : (char*)&buffer[0], std::streamsize(buffer.size())); + return 0; } -#endif //LODEPNG_COMPILE_DISK +#endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_DECODER @@ -5925,7 +5971,7 @@ unsigned decompress(std::vector& out, const std::vector& out, const unsigned char* in, size_t insize, @@ -5947,8 +5993,8 @@ unsigned compress(std::vector& out, const std::vector& out, unsigned& w, unsigned& h, const load_file(buffer, filename); return decode(out, w, h, buffer, colortype, bitdepth); } -#endif //LODEPNG_COMPILE_DECODER -#endif //LODEPNG_COMPILE_DISK +#endif /* LODEPNG_COMPILE_DECODER */ +#endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ENCODER unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, @@ -6086,7 +6132,7 @@ unsigned encode(const std::string& filename, { std::vector buffer; unsigned error = encode(buffer, in, w, h, colortype, bitdepth); - if(!error) save_file(buffer, filename); + if(!error) error = save_file(buffer, filename); return error; } @@ -6097,8 +6143,8 @@ unsigned encode(const std::string& filename, if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); } -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_ENCODER -#endif //LODEPNG_COMPILE_PNG -} //namespace lodepng +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_PNG */ +} /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ diff --git a/lodepng/lodepng.h b/lodepng/lodepng.h index ef2c820..0f87bc2 100644 --- a/lodepng/lodepng.h +++ b/lodepng/lodepng.h @@ -1,7 +1,7 @@ /* -LodePNG version 20140823 +LodePNG version 20150912 -Copyright (c) 2005-2014 Lode Vandevenne +Copyright (c) 2005-2015 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,12 +33,16 @@ freely, subject to the following restrictions: #include #endif /*__cplusplus*/ +extern const char* LODEPNG_VERSION_STRING; + /* The following #defines are used to create code sections. They can be disabled to disable code sections, which can give faster compile time and smaller binary. The "NO_COMPILE" defines are designed to be used to pass as defines to the compiler command to disable them without modifying this header, e.g. -DLODEPNG_NO_COMPILE_ZLIB for gcc. +In addition to those below, you can also define LODEPNG_NO_COMPILE_CRC to +allow implementing a custom lodepng_crc32. */ /*deflate & zlib. If disabled, you must specify alternative zlib functions in the custom_zlib field of the compress and decompress settings*/ @@ -211,8 +215,8 @@ Same as the other decode functions, but instead takes a filename as input. unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_DECODER +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_DECODER */ #ifdef LODEPNG_COMPILE_ENCODER /*Same as lodepng_encode_memory, but encodes to an std::vector. colortype @@ -235,9 +239,9 @@ unsigned encode(const std::string& filename, unsigned encode(const std::string& filename, const std::vector& in, unsigned w, unsigned h, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_ENCODER -} //namespace lodepng +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +} /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ #endif /*LODEPNG_COMPILE_PNG*/ @@ -568,9 +572,9 @@ typedef struct LodePNGColorProfile void lodepng_color_profile_init(LodePNGColorProfile* profile); /*Get a LodePNGColorProfile of the image.*/ -unsigned get_color_profile(LodePNGColorProfile* profile, - const unsigned char* image, unsigned w, unsigned h, - const LodePNGColorMode* mode_in); +unsigned lodepng_get_color_profile(LodePNGColorProfile* profile, + const unsigned char* image, unsigned w, unsigned h, + const LodePNGColorMode* mode_in); /*The function LodePNG uses internally to decide the PNG color with auto_convert. Chooses an optimal color model, e.g. grey if only grey pixels, palette if < 256 colors, ...*/ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, @@ -627,7 +631,7 @@ typedef struct LodePNGState LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ unsigned error; #ifdef LODEPNG_COMPILE_CPP - //For the lodepng::State subclass. + /* For the lodepng::State subclass. */ virtual ~LodePNGState(){} #endif } LodePNGState; @@ -677,7 +681,11 @@ Third byte: must be uppercase Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy */ -/*get the length of the data of the chunk. Total chunk length has 12 bytes more.*/ +/* +Gets the length of the data of the chunk. Total chunk length has 12 bytes more. +There must be at least 4 bytes to read from. If the result value is too large, +it may be corrupt data. +*/ unsigned lodepng_chunk_length(const unsigned char* chunk); /*puts the 4-byte type in null terminated string*/ @@ -805,7 +813,7 @@ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const #endif /*LODEPNG_COMPILE_DISK*/ #ifdef LODEPNG_COMPILE_CPP -//The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. +/* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */ namespace lodepng { #ifdef LODEPNG_COMPILE_PNG @@ -819,7 +827,7 @@ class State : public LodePNGState }; #ifdef LODEPNG_COMPILE_DECODER -//Same as other lodepng::decode, but using a State for more settings and information. +/* Same as other lodepng::decode, but using a State for more settings and information. */ unsigned decode(std::vector& out, unsigned& w, unsigned& h, State& state, const unsigned char* in, size_t insize); @@ -829,7 +837,7 @@ unsigned decode(std::vector& out, unsigned& w, unsigned& h, #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER -//Same as other lodepng::encode, but using a State for more settings and information. +/* Same as other lodepng::encode, but using a State for more settings and information. */ unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, State& state); @@ -849,32 +857,32 @@ void load_file(std::vector& buffer, const std::string& filename); Save the binary data in an std::vector to a file on disk. The file is overwritten without warning. */ -void save_file(const std::vector& buffer, const std::string& filename); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_PNG +unsigned save_file(const std::vector& buffer, const std::string& filename); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_PNG */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_DECODER -//Zlib-decompress an unsigned char buffer +/* Zlib-decompress an unsigned char buffer */ unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); -//Zlib-decompress an std::vector +/* Zlib-decompress an std::vector */ unsigned decompress(std::vector& out, const std::vector& in, const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); -#endif //LODEPNG_COMPILE_DECODER +#endif /* LODEPNG_COMPILE_DECODER */ #ifdef LODEPNG_COMPILE_ENCODER -//Zlib-compress an unsigned char buffer +/* Zlib-compress an unsigned char buffer */ unsigned compress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGCompressSettings& settings = lodepng_default_compress_settings); -//Zlib-compress an std::vector +/* Zlib-compress an std::vector */ unsigned compress(std::vector& out, const std::vector& in, const LodePNGCompressSettings& settings = lodepng_default_compress_settings); -#endif //LODEPNG_COMPILE_ENCODER -#endif //LODEPNG_COMPILE_ZLIB -} //namespace lodepng +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_ZLIB */ +} /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ /* @@ -888,8 +896,8 @@ TODO: [X] let the "isFullyOpaque" function check color keys and transparent palettes too [X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" [ ] don't stop decoding on errors like 69, 57, 58 (make warnings) -[ ] make option to choose if the raw image with non multiple of 8 bits per scanline should have padding bits or not [ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes +[ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ... */ #endif /*LODEPNG_H inclusion guard*/ @@ -1556,6 +1564,7 @@ yyyymmdd. Some changes aren't backwards compatible. Those are indicated with a (!) symbol. +*) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding. *) 23 aug 2014: Reduced needless memory usage of decoder. *) 28 jun 2014: Removed fix_png setting, always support palette OOB for simplicity. Made ColorProfile public. @@ -1698,5 +1707,5 @@ Domain: gmail dot com. Account: lode dot vandevenne. -Copyright (c) 2005-2014 Lode Vandevenne +Copyright (c) 2005-2015 Lode Vandevenne */ diff --git a/po/LINGUAS b/po/LINGUAS index 6ce41dd..850db9d 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -1,5 +1,7 @@ de es_AR +fr pl +pt_BR ru sq diff --git a/po/de.po b/po/de.po index f63a398..8999f0f 100644 --- a/po/de.po +++ b/po/de.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: telegram-purple\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-10-12 18:48+0200\n" -"PO-Revision-Date: 2015-10-12 16:50+0000\n" +"POT-Creation-Date: 2015-10-19 15:06+0200\n" +"PO-Revision-Date: 2015-10-19 13:11+0000\n" "Last-Translator: Ben Wiederhake \n" "Language-Team: German (http://www.transifex.com/telegram-purple-developers/telegram-purple/language/de/)\n" "MIME-Version: 1.0\n" @@ -50,281 +50,256 @@ msgstr "Bitte geben Sie Telefonnummern im internationalen Format ein, bestehend msgid "Query Failed" msgstr "Anfrage fehlgeschlagen" -#: ../telegram-purple.c:172 +#: ../telegram-purple.c:202 msgid "Secret chat terminated." msgstr "Geheimer Chat wurde beendet." -#: ../telegram-purple.c:215 +#: ../telegram-purple.c:247 msgid "Message marked as read." msgstr "Nachricht als gelesen markiert." -#: ../telegram-purple.c:475 +#: ../telegram-purple.c:484 #, c-format msgid "Invite link: %s" msgstr "Einladungslink: %s" -#: ../telegram-purple.c:498 ../telegram-purple.c:499 +#: ../telegram-purple.c:504 ../telegram-purple.c:505 msgid "Creating chat link failed" msgstr "Konnte keinen Link zum Chat erstellen" -#: ../telegram-purple.c:500 +#: ../telegram-purple.c:506 msgid "You need to be admin of the group to do that." msgstr "Sie müssen Gruppenadmin sein, um das zu tun." -#: ../telegram-purple.c:526 +#: ../telegram-purple.c:528 msgid "Chat joined" msgstr "Chat beigetreten" -#: ../telegram-purple.c:527 +#: ../telegram-purple.c:529 msgid "Chat added to list of chat rooms." msgstr "Chat der Liste von Chat-Räumen hinzugefügt." -#: ../telegram-purple.c:541 +#: ../telegram-purple.c:543 msgid "Start secret chat ..." msgstr "Beginne geheimen Chat ..." #. Generate Public Link -#: ../telegram-purple.c:547 +#: ../telegram-purple.c:549 msgid "Invite users by link ..." msgstr "Nutzer per Link einladen ..." #. Delete self from chat -#: ../telegram-purple.c:553 +#: ../telegram-purple.c:555 msgid "Delete and exit ..." msgstr "Löschen und verlassen ..." -#: ../telegram-purple.c:571 +#: ../telegram-purple.c:573 #, c-format msgid "" "Error, server public key not found at %s. Make sure that telegram-purple is " "installed properly." msgstr "Fehler, konnte öffentlichen Schlüssel nicht an %s finden. Stellen Sie sicher, dass telegram-purple korrekt installiert wurde." -#: ../telegram-purple.c:580 +#: ../telegram-purple.c:582 #, c-format msgid "Unable to sign on as %s: missing file %s." msgstr "Konnte nicht als %s einloggen: Fehlende Datei %s." -#: ../telegram-purple.c:584 +#: ../telegram-purple.c:586 msgid "" "Make sure telegram-purple is installed properly,\n" "including the .tglpub file." msgstr "Stellen Sie sicher, dass telegram-purple korrekt\ninstalliert wurde, inklusive der .tglpub Datei." -#: ../telegram-purple.c:602 +#: ../telegram-purple.c:604 #, c-format msgid "Unable to sign on as %s: phone number lacks country prefix." msgstr "Konnte nicht als %s anmelden: Telefonnummer hat kein Länderpräfix." -#: ../telegram-purple.c:606 +#: ../telegram-purple.c:608 msgid "" "Numbers must start with the full international\n" "prefix code, e.g. +49 for Germany." msgstr "Telefonnummern müssen mit dem vollen internationalen\nPräfix-Code beginnen, z.B. +49 für Deutschland." -#: ../telegram-purple.c:750 ../telegram-purple.c:751 +#: ../telegram-purple.c:733 ../telegram-purple.c:734 msgid "Cannot invite buddy to chat" msgstr "Kann den Freund nicht zum Chat einladen" -#: ../telegram-purple.c:752 +#: ../telegram-purple.c:735 msgid "Specified user does not exist." msgstr "Angegebener Benutzer existiert nicht." #. Login -#: ../telegram-purple.c:895 +#: ../telegram-purple.c:877 msgid "Password (two factor authentication)" msgstr "Passwort (Zwei-Faktor-Authentifizierung)" -#: ../telegram-purple.c:901 +#: ../telegram-purple.c:883 msgid "" "Fallback SMS verification\n" "(Helps when not using Pidgin and you aren't being prompted for the code)" msgstr "Ausweich SMS-Verifizierung\n(Hilfreich wenn Sie nicht Pidgin verwenden, und die Frage\nnach dem SMS-Code aus bleibt)" -#: ../telegram-purple.c:909 +#: ../telegram-purple.c:891 msgid "ask" msgstr "nachfragen" -#: ../telegram-purple.c:910 +#: ../telegram-purple.c:892 msgid "always" msgstr "immer" -#: ../telegram-purple.c:911 +#: ../telegram-purple.c:893 msgid "never" msgstr "nie" -#: ../telegram-purple.c:913 +#: ../telegram-purple.c:895 msgid "Accept secret chats" msgstr "Geheime Chats akzeptieren" -#: ../telegram-purple.c:918 +#: ../telegram-purple.c:900 msgid "Display buddies offline after (days)" msgstr "Freunde als offline anzeigen nach (Tage)" -#: ../telegram-purple.c:923 +#: ../telegram-purple.c:905 msgid "Fetch past history on first login" msgstr "Abrufen des bisherigen Verlaufs beim ersten Login" -#: ../telegram-purple.c:928 +#: ../telegram-purple.c:910 msgid "" "Don't fetch history older than (days)\n" "(0 for unlimited)" msgstr "Abrufen des Verlaufs begrenzen auf (Tage)\n(0 für unbegrenzt)" #. Chats -#: ../telegram-purple.c:936 +#: ../telegram-purple.c:918 msgid "Add all group chats to buddy list" msgstr "Alle Gruppenchats in die Freundesliste einfügen" #. Read notifications -#: ../telegram-purple.c:944 +#: ../telegram-purple.c:926 msgid "Display notices of receipt" msgstr "Empfangsbestätigungen anzeigen" -#: ../telegram-purple.c:949 +#: ../telegram-purple.c:931 msgid "Send notices of receipt when present" msgstr "Empfangsbestätigungen senden wenn anwesend" -#: ../tgp-2prpl.c:386 ../tgp-request.c:130 +#: ../tgp-2prpl.c:167 ../tgp-request.c:130 msgid "First name" msgstr "Vorname" -#: ../tgp-2prpl.c:387 ../tgp-request.c:132 +#: ../tgp-2prpl.c:168 ../tgp-request.c:132 msgid "Last name" msgstr "Nachname" -#: ../tgp-2prpl.c:389 +#: ../tgp-2prpl.c:170 msgid "Name" msgstr "Name" -#: ../tgp-2prpl.c:394 ../tgp-request.c:246 ../tgp-request.c:250 +#: ../tgp-2prpl.c:175 ../tgp-request.c:246 ../tgp-request.c:250 #: ../tgp-request.c:254 msgid "Username" msgstr "Benutzername" -#: ../tgp-2prpl.c:399 +#: ../tgp-2prpl.c:180 msgid "Last seen" msgstr "Zuletzt gesehen" -#: ../tgp-2prpl.c:404 +#: ../tgp-2prpl.c:185 msgid "Phone" msgstr "Telefonnummer" -#: ../tgp-2prpl.c:417 +#: ../tgp-2prpl.c:197 msgid "Waiting for the user to get online ..." msgstr "Warte auf Anmeldung des Benutzers ..." -#: ../tgp-2prpl.c:421 +#: ../tgp-2prpl.c:201 msgid "Self destruction timer" msgstr "Selbstzerstörungs-Timer" -#: ../tgp-2prpl.c:427 +#: ../tgp-2prpl.c:207 msgid "Off" msgstr "Aus" -#: ../tgp-2prpl.c:434 +#: ../tgp-2prpl.c:214 msgid "Secret key" msgstr "Geheimer Schlüssel" -#: ../tgp-msg.c:55 +#: ../tgp-msg.c:53 #, c-format msgid "%2$s created chat %1$s." msgstr "%2$s hat den Chat %1$s erstellt." -#: ../tgp-msg.c:58 +#: ../tgp-msg.c:56 #, c-format msgid "%2$s changed title to %1$s." msgstr "%2$s hat den Titel zu %1$s geändert." -#: ../tgp-msg.c:61 +#: ../tgp-msg.c:59 #, c-format msgid "%s changed photo." msgstr "%s hat das Photo geändert." -#: ../tgp-msg.c:64 +#: ../tgp-msg.c:62 #, c-format msgid "%s deleted photo." msgstr "%s hat das Photo gelöscht." -#: ../tgp-msg.c:72 +#: ../tgp-msg.c:70 #, c-format msgid "%1$s added user %2$s by link." msgstr "%1$s fügte Benutzer %2$s per Link hinzu." -#: ../tgp-msg.c:85 +#: ../tgp-msg.c:83 #, c-format msgid "%2$s added user %1$s." msgstr "%2$s hat den Nutzer %1$s hinzufügt." -#: ../tgp-msg.c:107 +#: ../tgp-msg.c:104 #, c-format msgid "%1$s deleted user %2$s." msgstr "%1$s entfernte Benutzer %2$s." -#: ../tgp-msg.c:120 +#: ../tgp-msg.c:118 #, c-format msgid "%2$s deleted user %1$s." msgstr "%2$s entfernte Benutzer %1$s." -#: ../tgp-msg.c:125 +#: ../tgp-msg.c:123 #, c-format msgid "%2$s set self destruction timer to %1$d seconds." msgstr "%2$s setzte Selbstzerstörungs-Timer auf %1$d Sekunden." -#: ../tgp-msg.c:128 +#: ../tgp-msg.c:126 #, c-format msgid "%2$s marked %1$d messages read." msgstr "%2$s markierte %1$d Nachrichten als gelesen." -#: ../tgp-msg.c:131 +#: ../tgp-msg.c:129 #, c-format msgid "%2$s deleted %1$d messages." msgstr "%2$s entfernte %1$d Nachrichten." -#: ../tgp-msg.c:134 +#: ../tgp-msg.c:132 #, c-format msgid "%2$s made a screenshot of %1$d messages." msgstr "%2$s machte einen Screenshot von %1$d Nachrichten." -#: ../tgp-msg.c:137 -#, c-format -msgid "%2$s updated to layer %1$d." -msgstr "%2$s wechselte zu Layer %1$d." - -#: ../tgp-msg.c:140 -#, c-format -msgid "%2$s requests rekey #%1$016llx." -msgstr "%2$s beantragt neuen Schlüssel #%1$016llx." - -#: ../tgp-msg.c:143 -#, c-format -msgid "%2$s accepts rekey #%1$016llx." -msgstr "%2$s akzeptiert neuen Schlüssel #%1$016llx." - -#: ../tgp-msg.c:146 -#, c-format -msgid "%2$s commits rekey #%1$016llx." -msgstr "%2$s bestätigt neuen Schlüssel #%1$016llx." - -#: ../tgp-msg.c:149 -#, c-format -msgid "%2$s aborts rekey #%1$016llx." -msgstr "%2$s akzeptiert neuen Schlüssel #%1$016llx." - -#: ../tgp-msg.c:173 +#: ../tgp-msg.c:156 #, c-format msgid "Sending message failed. %d: %s" msgstr "Absenden der Nachricht fehlgeschlagen. %d: %s" -#: ../tgp-msg.c:251 +#: ../tgp-msg.c:259 msgid "Sending image failed." msgstr "Absenden des Bilds fehlgeschlagen." -#: ../tgp-msg.c:265 +#: ../tgp-msg.c:273 msgid "Sorry, sending documents to encrypted chats not yet supported." msgstr "Tut uns Leid, aber das Versenden von Dokumenten in verschlüsselten Chats wird noch nicht unterstützt." -#: ../tgp-msg.c:352 +#: ../tgp-msg.c:360 #, c-format msgid "%s sent a sticker." msgstr "%s hat einen Sticker gesendet." @@ -461,49 +436,49 @@ msgstr "Möchten Sie eine neue Gruppe \"%s\" erstellen?" #. This should be the language's timestamp format. #. * This is preceded by a colon. -#: ../tgp-utils.c:39 +#: ../tgp-utils.c:33 msgid "%d.%m.%Y %H:%M" msgstr "%d.%m.%Y %H:%M" #. This is preceded by a colon. -#: ../tgp-utils.c:60 +#: ../tgp-utils.c:54 #, c-format msgid "recently" msgstr "Kürzlich" #. This is preceded by a colon. -#: ../tgp-utils.c:64 +#: ../tgp-utils.c:58 #, c-format msgid "last week" msgstr "Letzte Woche" #. This is preceded by a colon. -#: ../tgp-utils.c:68 +#: ../tgp-utils.c:62 #, c-format msgid "last month" msgstr "Letzten Monat" #. This is preceded by a colon. It refers to a point on time. -#: ../tgp-utils.c:72 +#: ../tgp-utils.c:66 msgid "unknown" msgstr "Unbekannt" -#: ../tgp-chat.c:83 +#: ../tgp-chat.c:79 msgid "You have already left this chat." msgstr "Du hast diesen Chat bereits verlassen." -#: ../tgp-chat.c:133 +#: ../tgp-chat.c:122 msgid "Subject:" msgstr "Thema:" -#: ../tgp-chat.c:139 +#: ../tgp-chat.c:128 msgid "Invite link:" msgstr "Einladungslink:" -#: ../tgp-chat.c:145 +#: ../tgp-chat.c:134 msgid "Chat ID:" msgstr "Chat ID:" -#: ../tgp-chat.c:244 +#: ../tgp-chat.c:232 msgid "Users" msgstr "Benutzer" diff --git a/po/es_AR.po b/po/es_AR.po index e88ac1d..4881c13 100644 --- a/po/es_AR.po +++ b/po/es_AR.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: telegram-purple\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-10-12 18:48+0200\n" -"PO-Revision-Date: 2015-10-13 07:56+0000\n" -"Last-Translator: KNTRO \n" +"POT-Creation-Date: 2015-10-19 15:06+0200\n" +"PO-Revision-Date: 2015-10-19 13:11+0000\n" +"Last-Translator: Ben Wiederhake \n" "Language-Team: Spanish (Argentina) (http://www.transifex.com/telegram-purple-developers/telegram-purple/language/es_AR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -49,281 +49,256 @@ msgstr "Por favor, ingresá sólo números en el formato de números de teléfon msgid "Query Failed" msgstr "Falló la consulta" -#: ../telegram-purple.c:172 +#: ../telegram-purple.c:202 msgid "Secret chat terminated." msgstr "Finalizó la conversación secreta." -#: ../telegram-purple.c:215 +#: ../telegram-purple.c:247 msgid "Message marked as read." msgstr "Mensaje marcado como leído." -#: ../telegram-purple.c:475 +#: ../telegram-purple.c:484 #, c-format msgid "Invite link: %s" msgstr "Enlace de invitación: %s" -#: ../telegram-purple.c:498 ../telegram-purple.c:499 +#: ../telegram-purple.c:504 ../telegram-purple.c:505 msgid "Creating chat link failed" msgstr "Falló la creación del enlace de conversación" -#: ../telegram-purple.c:500 +#: ../telegram-purple.c:506 msgid "You need to be admin of the group to do that." msgstr "Necesitás ser administrador del grupo para hacer eso." -#: ../telegram-purple.c:526 +#: ../telegram-purple.c:528 msgid "Chat joined" msgstr "Unido a la conversación" -#: ../telegram-purple.c:527 +#: ../telegram-purple.c:529 msgid "Chat added to list of chat rooms." msgstr "Conversación agregada a la lista de salas de conversaciones." -#: ../telegram-purple.c:541 +#: ../telegram-purple.c:543 msgid "Start secret chat ..." msgstr "Iniciar conversación secreta…" #. Generate Public Link -#: ../telegram-purple.c:547 +#: ../telegram-purple.c:549 msgid "Invite users by link ..." msgstr "Invitar a usuarios mediante un enlace…" #. Delete self from chat -#: ../telegram-purple.c:553 +#: ../telegram-purple.c:555 msgid "Delete and exit ..." msgstr "Eliminar y salir…" -#: ../telegram-purple.c:571 +#: ../telegram-purple.c:573 #, c-format msgid "" "Error, server public key not found at %s. Make sure that telegram-purple is " "installed properly." msgstr "Ocurrió un error: no se encontró una clave pública de servidor en %s. Asegurate de que telegram-purple esté correctamente instalado." -#: ../telegram-purple.c:580 +#: ../telegram-purple.c:582 #, c-format msgid "Unable to sign on as %s: missing file %s." msgstr "No se pudo iniciar sesión como %s: falta el archivo %s." -#: ../telegram-purple.c:584 +#: ../telegram-purple.c:586 msgid "" "Make sure telegram-purple is installed properly,\n" "including the .tglpub file." msgstr "Asegurate de que telegram-purple esté correctamente instalado,\nincluyendo el archivo \".tglpub\"." -#: ../telegram-purple.c:602 +#: ../telegram-purple.c:604 #, c-format msgid "Unable to sign on as %s: phone number lacks country prefix." msgstr "No se pudo iniciar sesión como %s: al número de teléfono le falta el código de país." -#: ../telegram-purple.c:606 +#: ../telegram-purple.c:608 msgid "" "Numbers must start with the full international\n" "prefix code, e.g. +49 for Germany." msgstr "Los números deben comenzar con\nel código de país. Por ejemplo: \"+54\" para Argentina." -#: ../telegram-purple.c:750 ../telegram-purple.c:751 +#: ../telegram-purple.c:733 ../telegram-purple.c:734 msgid "Cannot invite buddy to chat" msgstr "No se pudo invitar al contacto a la conversación" -#: ../telegram-purple.c:752 +#: ../telegram-purple.c:735 msgid "Specified user does not exist." msgstr "El usuario especificado no existe." #. Login -#: ../telegram-purple.c:895 +#: ../telegram-purple.c:877 msgid "Password (two factor authentication)" msgstr "Contraseña (autenticación de 2 pasos)" -#: ../telegram-purple.c:901 +#: ../telegram-purple.c:883 msgid "" "Fallback SMS verification\n" "(Helps when not using Pidgin and you aren't being prompted for the code)" msgstr "Verificación por mensaje de texto\n(Sirve para cuando no estás usando Pidgin y no se te pide el código)" -#: ../telegram-purple.c:909 +#: ../telegram-purple.c:891 msgid "ask" msgstr "pedir" -#: ../telegram-purple.c:910 +#: ../telegram-purple.c:892 msgid "always" msgstr "siempre" -#: ../telegram-purple.c:911 +#: ../telegram-purple.c:893 msgid "never" msgstr "nunca" -#: ../telegram-purple.c:913 +#: ../telegram-purple.c:895 msgid "Accept secret chats" msgstr "Aceptar conversaciones secretas" -#: ../telegram-purple.c:918 +#: ../telegram-purple.c:900 msgid "Display buddies offline after (days)" msgstr "Mostrar contactos desconectados después de (días)" -#: ../telegram-purple.c:923 +#: ../telegram-purple.c:905 msgid "Fetch past history on first login" msgstr "Recuperar historial en el primer inicio de sesión" -#: ../telegram-purple.c:928 +#: ../telegram-purple.c:910 msgid "" "Don't fetch history older than (days)\n" "(0 for unlimited)" msgstr "No recuperar el historial anterior a (días)\n(ingresá \"0\" para no aplicar límites)" #. Chats -#: ../telegram-purple.c:936 +#: ../telegram-purple.c:918 msgid "Add all group chats to buddy list" msgstr "Agregar todas las conversaciones grupales a la lista del contacto" #. Read notifications -#: ../telegram-purple.c:944 +#: ../telegram-purple.c:926 msgid "Display notices of receipt" msgstr "Mostrar acuses de recibo" -#: ../telegram-purple.c:949 +#: ../telegram-purple.c:931 msgid "Send notices of receipt when present" msgstr "Enviar acuses de recibo al estar presente" -#: ../tgp-2prpl.c:386 ../tgp-request.c:130 +#: ../tgp-2prpl.c:167 ../tgp-request.c:130 msgid "First name" msgstr "Nombre" -#: ../tgp-2prpl.c:387 ../tgp-request.c:132 +#: ../tgp-2prpl.c:168 ../tgp-request.c:132 msgid "Last name" msgstr "Apellido" -#: ../tgp-2prpl.c:389 +#: ../tgp-2prpl.c:170 msgid "Name" msgstr "Apodo" -#: ../tgp-2prpl.c:394 ../tgp-request.c:246 ../tgp-request.c:250 +#: ../tgp-2prpl.c:175 ../tgp-request.c:246 ../tgp-request.c:250 #: ../tgp-request.c:254 msgid "Username" msgstr "Nombre de usuario" -#: ../tgp-2prpl.c:399 +#: ../tgp-2prpl.c:180 msgid "Last seen" msgstr "Último inicio de sesión" -#: ../tgp-2prpl.c:404 +#: ../tgp-2prpl.c:185 msgid "Phone" msgstr "Teléfono" -#: ../tgp-2prpl.c:417 +#: ../tgp-2prpl.c:197 msgid "Waiting for the user to get online ..." msgstr "Esperando a que el usuario se conecte…" -#: ../tgp-2prpl.c:421 +#: ../tgp-2prpl.c:201 msgid "Self destruction timer" msgstr "Contador autodestructivo" -#: ../tgp-2prpl.c:427 +#: ../tgp-2prpl.c:207 msgid "Off" msgstr "Desactivado" -#: ../tgp-2prpl.c:434 +#: ../tgp-2prpl.c:214 msgid "Secret key" msgstr "Clave secreta" -#: ../tgp-msg.c:55 +#: ../tgp-msg.c:53 #, c-format msgid "%2$s created chat %1$s." msgstr "%2$s creó la conversación %1$s." -#: ../tgp-msg.c:58 +#: ../tgp-msg.c:56 #, c-format msgid "%2$s changed title to %1$s." msgstr "%2$s cambió el título a %1$s." -#: ../tgp-msg.c:61 +#: ../tgp-msg.c:59 #, c-format msgid "%s changed photo." msgstr "%s cambió la foto." -#: ../tgp-msg.c:64 +#: ../tgp-msg.c:62 #, c-format msgid "%s deleted photo." msgstr "%s eliminó la foto." -#: ../tgp-msg.c:72 +#: ../tgp-msg.c:70 #, c-format msgid "%1$s added user %2$s by link." msgstr "%1$s agregó al usuario %2$s mediante un enlace." -#: ../tgp-msg.c:85 +#: ../tgp-msg.c:83 #, c-format msgid "%2$s added user %1$s." msgstr "%2$s agregó al usuario %1$s." -#: ../tgp-msg.c:107 +#: ../tgp-msg.c:104 #, c-format msgid "%1$s deleted user %2$s." msgstr "%1$s eliminó al usuario %2$s." -#: ../tgp-msg.c:120 +#: ../tgp-msg.c:118 #, c-format msgid "%2$s deleted user %1$s." msgstr "%2$s eliminó al usuario %1$s." -#: ../tgp-msg.c:125 +#: ../tgp-msg.c:123 #, c-format msgid "%2$s set self destruction timer to %1$d seconds." msgstr "%2$s estableció un contador autodestructivo a %1$d segundos." -#: ../tgp-msg.c:128 +#: ../tgp-msg.c:126 #, c-format msgid "%2$s marked %1$d messages read." msgstr "%2$s marcó %1$d mensajes como leídos." -#: ../tgp-msg.c:131 +#: ../tgp-msg.c:129 #, c-format msgid "%2$s deleted %1$d messages." msgstr "%2$s eliminó %1$d mensajes." -#: ../tgp-msg.c:134 +#: ../tgp-msg.c:132 #, c-format msgid "%2$s made a screenshot of %1$d messages." msgstr "%2$s tomó una captura de pantalla de %1$d mensajes." -#: ../tgp-msg.c:137 -#, c-format -msgid "%2$s updated to layer %1$d." -msgstr "%2$s actualizado a capa %1$d." - -#: ../tgp-msg.c:140 -#, c-format -msgid "%2$s requests rekey #%1$016llx." -msgstr "%2$s solicitó una nueva clave #%1$016llx." - -#: ../tgp-msg.c:143 -#, c-format -msgid "%2$s accepts rekey #%1$016llx." -msgstr "%2$s acepta una nueva clave #%1$016llx." - -#: ../tgp-msg.c:146 -#, c-format -msgid "%2$s commits rekey #%1$016llx." -msgstr "%2$s ejecuta una nueva clave #%1$016llx." - -#: ../tgp-msg.c:149 -#, c-format -msgid "%2$s aborts rekey #%1$016llx." -msgstr "%2$s cancela una nueva clave #%1$016llx." - -#: ../tgp-msg.c:173 +#: ../tgp-msg.c:156 #, c-format msgid "Sending message failed. %d: %s" msgstr "Falló el envío de mensajes. %d: %s" -#: ../tgp-msg.c:251 +#: ../tgp-msg.c:259 msgid "Sending image failed." msgstr "Falló el envío de imágenes." -#: ../tgp-msg.c:265 +#: ../tgp-msg.c:273 msgid "Sorry, sending documents to encrypted chats not yet supported." msgstr "Lo sentimos, pero no se soporta el envío de documentos a conversaciones cifradas." -#: ../tgp-msg.c:352 +#: ../tgp-msg.c:360 #, c-format msgid "%s sent a sticker." msgstr "%s envió un sticker." @@ -460,49 +435,49 @@ msgstr "¿Querés crear una nueva conversación grupal llamada \"%s\"?" #. This should be the language's timestamp format. #. * This is preceded by a colon. -#: ../tgp-utils.c:39 +#: ../tgp-utils.c:33 msgid "%d.%m.%Y %H:%M" msgstr "%Y.%m.%d - %H:%M" #. This is preceded by a colon. -#: ../tgp-utils.c:60 +#: ../tgp-utils.c:54 #, c-format msgid "recently" msgstr "recientemente" #. This is preceded by a colon. -#: ../tgp-utils.c:64 +#: ../tgp-utils.c:58 #, c-format msgid "last week" msgstr "la semana pasada" #. This is preceded by a colon. -#: ../tgp-utils.c:68 +#: ../tgp-utils.c:62 #, c-format msgid "last month" msgstr "el mes pasado" #. This is preceded by a colon. It refers to a point on time. -#: ../tgp-utils.c:72 +#: ../tgp-utils.c:66 msgid "unknown" msgstr "[desconocido]" -#: ../tgp-chat.c:83 +#: ../tgp-chat.c:79 msgid "You have already left this chat." msgstr "Ya abandonaste esta conversación." -#: ../tgp-chat.c:133 +#: ../tgp-chat.c:122 msgid "Subject:" msgstr "Asunto:" -#: ../tgp-chat.c:139 +#: ../tgp-chat.c:128 msgid "Invite link:" msgstr "Enlace de invitación:" -#: ../tgp-chat.c:145 +#: ../tgp-chat.c:134 msgid "Chat ID:" msgstr "Identificación de conversación:" -#: ../tgp-chat.c:244 +#: ../tgp-chat.c:232 msgid "Users" msgstr "Usuarios" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..ddb72e3 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,483 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Hugues Morisset , 2015 +msgid "" +msgstr "" +"Project-Id-Version: telegram-purple\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-10-19 15:06+0200\n" +"PO-Revision-Date: 2015-10-19 13:11+0000\n" +"Last-Translator: Ben Wiederhake \n" +"Language-Team: French (http://www.transifex.com/telegram-purple-developers/telegram-purple/language/fr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: ../telegram-base.c:477 +msgid "Login canceled" +msgstr "Connexion annulé" + +#: ../telegram-base.c:477 +msgid "" +"Authentication export to remote data centers failed, login not possible." +msgstr "Authentification au data center distant échoué, connexion impossible." + +#: ../telegram-base.c:524 +msgid "Couldn't create group" +msgstr "N'a pas pu créer le groupe" + +#: ../telegram-base.c:524 +msgid "Select at least one other user" +msgstr "Sélectionné au moins un autre utilisateur" + +#: ../telegram-base.c:532 +msgid "Invalid phone number" +msgstr "Numéro de téléphone invalide" + +#: ../telegram-base.c:533 +msgid "" +"Please enter only numbers in the international phone number format, a leading + following by the country prefix and the phone number.\n" +"Do not use any other special chars." +msgstr "Entré seulement des numéro dans le champs pour le numéro international, un + suivi du préfixe de pays et du numéro de téléphone.\nN’utilise aucun autre caractère spécial." + +#: ../telegram-base.c:647 +msgid "Query Failed" +msgstr "Requête échoué" + +#: ../telegram-purple.c:202 +msgid "Secret chat terminated." +msgstr "Conversation secrète terminé." + +#: ../telegram-purple.c:247 +msgid "Message marked as read." +msgstr "Message marqué comme lu." + +#: ../telegram-purple.c:484 +#, c-format +msgid "Invite link: %s" +msgstr "Lien d'invitation: %s" + +#: ../telegram-purple.c:504 ../telegram-purple.c:505 +msgid "Creating chat link failed" +msgstr "Création du lien d'invitation échoué" + +#: ../telegram-purple.c:506 +msgid "You need to be admin of the group to do that." +msgstr "Vous devez êtes administrateur du groupe pour faire cela." + +#: ../telegram-purple.c:528 +msgid "Chat joined" +msgstr "Conversation jointe." + +#: ../telegram-purple.c:529 +msgid "Chat added to list of chat rooms." +msgstr "Conversation ajouté dans la liste de conversations." + +#: ../telegram-purple.c:543 +msgid "Start secret chat ..." +msgstr "Commencé une conversation secrète ..." + +#. Generate Public Link +#: ../telegram-purple.c:549 +msgid "Invite users by link ..." +msgstr "Invité des utilisateurs avec un lien ..." + +#. Delete self from chat +#: ../telegram-purple.c:555 +msgid "Delete and exit ..." +msgstr "Supprimer et quitter ..." + +#: ../telegram-purple.c:573 +#, c-format +msgid "" +"Error, server public key not found at %s. Make sure that telegram-purple is " +"installed properly." +msgstr "Erreur, la clé public du serveur n'a pas été trouvé ici: %s. Vérifié que telegram-purple soit proprement installé." + +#: ../telegram-purple.c:582 +#, c-format +msgid "Unable to sign on as %s: missing file %s." +msgstr "Impossible de se connecté comme %s: fichier manquant: %s." + +#: ../telegram-purple.c:586 +msgid "" +"Make sure telegram-purple is installed properly,\n" +"including the .tglpub file." +msgstr "Vérifié que telegram-purple soit proprement installé,\navec le fichier .tglpub." + +#: ../telegram-purple.c:604 +#, c-format +msgid "Unable to sign on as %s: phone number lacks country prefix." +msgstr "Impossible de se connecter avec le compte %s: le numéro de téléphone doit contenir un préfixe de pays." + +#: ../telegram-purple.c:608 +msgid "" +"Numbers must start with the full international\n" +"prefix code, e.g. +49 for Germany." +msgstr "Les numéros de téléphone doit commencé avec le numéro international du pays,\nex: +33 pour la France." + +#: ../telegram-purple.c:733 ../telegram-purple.c:734 +msgid "Cannot invite buddy to chat" +msgstr "Impossible d'ajouté le contact á la conversation" + +#: ../telegram-purple.c:735 +msgid "Specified user does not exist." +msgstr "L'utilisateur spécifier n'existe pas." + +#. Login +#: ../telegram-purple.c:877 +msgid "Password (two factor authentication)" +msgstr "Mot de passe (authentification á deux facteurs)" + +#: ../telegram-purple.c:883 +msgid "" +"Fallback SMS verification\n" +"(Helps when not using Pidgin and you aren't being prompted for the code)" +msgstr "Vérification par SMS\n(Cela aide si vous n’utilisé pas Pidgin et que vous n'êtes pas notifier pour le code)" + +#: ../telegram-purple.c:891 +msgid "ask" +msgstr "demander" + +#: ../telegram-purple.c:892 +msgid "always" +msgstr "toujours" + +#: ../telegram-purple.c:893 +msgid "never" +msgstr "jamais" + +#: ../telegram-purple.c:895 +msgid "Accept secret chats" +msgstr "Accepté la conversation secrète" + +#: ../telegram-purple.c:900 +msgid "Display buddies offline after (days)" +msgstr "Affiché les contact déconnecté après (jours)" + +#: ../telegram-purple.c:905 +msgid "Fetch past history on first login" +msgstr "Récupérer l'historique á la première connexion" + +#: ../telegram-purple.c:910 +msgid "" +"Don't fetch history older than (days)\n" +"(0 for unlimited)" +msgstr "Ne pas récupérer l'historique plus vieux de (jours)\n(0 pour infinie)" + +#. Chats +#: ../telegram-purple.c:918 +msgid "Add all group chats to buddy list" +msgstr "Ajouté tous les membre de la conversation dans la liste de contact" + +#. Read notifications +#: ../telegram-purple.c:926 +msgid "Display notices of receipt" +msgstr "Affiché les notifications de réception" + +#: ../telegram-purple.c:931 +msgid "Send notices of receipt when present" +msgstr "Envoyé des notification de réception quand vous êtes présent." + +#: ../tgp-2prpl.c:167 ../tgp-request.c:130 +msgid "First name" +msgstr "Prénom" + +#: ../tgp-2prpl.c:168 ../tgp-request.c:132 +msgid "Last name" +msgstr "Nom de famille" + +#: ../tgp-2prpl.c:170 +msgid "Name" +msgstr "Nom" + +#: ../tgp-2prpl.c:175 ../tgp-request.c:246 ../tgp-request.c:250 +#: ../tgp-request.c:254 +msgid "Username" +msgstr "Nom d'utilisateur" + +#: ../tgp-2prpl.c:180 +msgid "Last seen" +msgstr "Dernière fois vu" + +#: ../tgp-2prpl.c:185 +msgid "Phone" +msgstr "Téléphone" + +#: ../tgp-2prpl.c:197 +msgid "Waiting for the user to get online ..." +msgstr "En attente de connexion de l'utilisateur ..." + +#: ../tgp-2prpl.c:201 +msgid "Self destruction timer" +msgstr "Compte a rebours d’auto destruction" + +#: ../tgp-2prpl.c:207 +msgid "Off" +msgstr "Déconnecté" + +#: ../tgp-2prpl.c:214 +msgid "Secret key" +msgstr "Clé secrète" + +#: ../tgp-msg.c:53 +#, c-format +msgid "%2$s created chat %1$s." +msgstr "%2$s a créer la conversation %1$s." + +#: ../tgp-msg.c:56 +#, c-format +msgid "%2$s changed title to %1$s." +msgstr "%2$s a changé le titre pour %1$s." + +#: ../tgp-msg.c:59 +#, c-format +msgid "%s changed photo." +msgstr "%s á changé ca photo." + +#: ../tgp-msg.c:62 +#, c-format +msgid "%s deleted photo." +msgstr "%s a supprimé la photo." + +#: ../tgp-msg.c:70 +#, c-format +msgid "%1$s added user %2$s by link." +msgstr "%1$s a ajouté l'utilisateur %2$s avec un lien." + +#: ../tgp-msg.c:83 +#, c-format +msgid "%2$s added user %1$s." +msgstr "%2$s a ajouté l'utilisateur %1$s." + +#: ../tgp-msg.c:104 +#, c-format +msgid "%1$s deleted user %2$s." +msgstr "%1$s a supprimé l'utilisateur %2$s." + +#: ../tgp-msg.c:118 +#, c-format +msgid "%2$s deleted user %1$s." +msgstr "%2$s a supprimé l'utilisateur %1$s." + +#: ../tgp-msg.c:123 +#, c-format +msgid "%2$s set self destruction timer to %1$d seconds." +msgstr "%2$s a mis le compte a rebours d'auto destruction a %1$d secondes." + +#: ../tgp-msg.c:126 +#, c-format +msgid "%2$s marked %1$d messages read." +msgstr "%2$s a marqué les messages de %1$d lu." + +#: ../tgp-msg.c:129 +#, c-format +msgid "%2$s deleted %1$d messages." +msgstr "%2$s a supprimé les messages de %1$d." + +#: ../tgp-msg.c:132 +#, c-format +msgid "%2$s made a screenshot of %1$d messages." +msgstr "%2$s a pris un copie d'écran des messages de %1$d." + +#: ../tgp-msg.c:156 +#, c-format +msgid "Sending message failed. %d: %s" +msgstr "L'envoi du message a échoué. %d: %s" + +#: ../tgp-msg.c:259 +msgid "Sending image failed." +msgstr "L'envoie de l'image á échoué." + +#: ../tgp-msg.c:273 +msgid "Sorry, sending documents to encrypted chats not yet supported." +msgstr "Envoyé des documents dans un conversation secrète n'est pas encore supporté." + +#: ../tgp-msg.c:360 +#, c-format +msgid "%s sent a sticker." +msgstr "%s a envoyé un sticker." + +#: ../tgp-net.c:326 +msgid "Cannot connect to server" +msgstr "Impossible de se connecté au serveur" + +#: ../tgp-net.c:371 +msgid "Lost connection to the server ..." +msgstr "Connexion au serveur perdu ..." + +#: ../tgp-request.c:76 ../tgp-request.c:137 +msgid "Login code" +msgstr "Code de connexion" + +#: ../tgp-request.c:76 +msgid "Enter login code" +msgstr "Entré le code de connexion" + +#: ../tgp-request.c:76 +msgid "" +"Telegram wants to verify your identity. Please enter the code that you have " +"received via SMS." +msgstr "Telegram veut vérifié votre identité. Veuillez entré le code de vérification reçu par SMS." + +#: ../tgp-request.c:77 +msgid "the code" +msgstr "le code" + +#: ../tgp-request.c:77 ../tgp-request.c:141 ../tgp-request.c:259 +msgid "OK" +msgstr "OK" + +#: ../tgp-request.c:78 ../tgp-request.c:142 ../tgp-request.c:260 +msgid "Cancel" +msgstr "Annulé" + +#: ../tgp-request.c:85 +msgid "What is your SMS verification code?" +msgstr "Quelle est le code de vérification envoyé par SMS ?" + +#: ../tgp-request.c:129 +msgid "Registration" +msgstr "Enregistrement" + +#: ../tgp-request.c:136 +msgid "Authorization" +msgstr "Autorisation" + +#: ../tgp-request.c:141 +msgid "Register" +msgstr "Enregistré" + +#: ../tgp-request.c:141 +msgid "Please register your phone number." +msgstr "Enregistré votre numéro de téléphone." + +#. purple_request API not available +#: ../tgp-request.c:144 +msgid "" +"Phone number is not registered. Please register your phone on a different " +"client." +msgstr "Numéro téléphone non enregistré. Enregistré un numéro de téléphone sur un appareils différent." + +#: ../tgp-request.c:146 +msgid "Not Registered" +msgstr "Non enregistré" + +#: ../tgp-request.c:169 +msgid "Password" +msgstr "Mot de passe" + +#: ../tgp-request.c:174 +msgid "Enter password" +msgstr "Entré le mot de passe" + +#: ../tgp-request.c:174 +msgid "Enter password for two factor authentication" +msgstr "Entré le mot de passe pour l'authentification a deux facteur" + +#: ../tgp-request.c:177 +msgid "" +"No password set for two factor authentication. Please enter it in the " +"extended settings." +msgstr "Pas de mot de passe a deux facteur spécifié. Entré en un dans la configuration étendu." + +#: ../tgp-request.c:179 +msgid "Password invalid" +msgstr "Mot de passe invalide" + +#: ../tgp-request.c:207 +#, c-format +msgid "Accept Secret Chat '%s'?" +msgstr "Accepté la conversation secrète '%s'?" + +#: ../tgp-request.c:208 +msgid "Secret Chat" +msgstr "Conversation secrète" + +#: ../tgp-request.c:208 +msgid "" +"Secret chats can only have one end point. If you accept a secret chat on " +"this device, its messages will not be available anywhere else. If you " +"decline, you can accept the chat on other devices." +msgstr "Les conversations secrète ne peuvent avoir qu'une seul destination. Si vous accepté la conversation sur cette appareils, les messages ne seront pas disponible sur les autre appareils. Si vous refusé, vous pouver accepté la conversation sur les autre appareils." + +#: ../tgp-request.c:243 +msgid "" +"Invite at least one additional user (Autocompletion available).\n" +"You can add more users once the chat was created." +msgstr "Invité au moins un utilisateur supplémentaire (Autocompletion disponible).\nVous pourrer ajouté plus d'utilisateurs une fois la conversation créer." + +#. FIXME: This dialog is pointless. It only asks whether the user wants to +#. create a new chat. +#. This should be merged with the next dialog. +#. TODO: This still displays "Cancel" and "Accept", no matter $LANG +#: ../tgp-request.c:259 ../tgp-request.c:275 +msgid "Create group chat" +msgstr "Créer un groupe de conversation" + +#: ../tgp-request.c:259 +msgid "Invite users" +msgstr "Invité des utilisateurs" + +#: ../tgp-request.c:269 +msgid "Chat doesn't exist (yet)" +msgstr "La conversation n'existe pas (encore)" + +#: ../tgp-request.c:270 +#, c-format +msgid "Do you want to create a new group chat named '%s'?" +msgstr "Voulez vous créer un nouveau groupe appelé %s ?" + +#. This should be the language's timestamp format. +#. * This is preceded by a colon. +#: ../tgp-utils.c:33 +msgid "%d.%m.%Y %H:%M" +msgstr "%d.%m.%Y %H:%M" + +#. This is preceded by a colon. +#: ../tgp-utils.c:54 +#, c-format +msgid "recently" +msgstr "récamment" + +#. This is preceded by a colon. +#: ../tgp-utils.c:58 +#, c-format +msgid "last week" +msgstr "semaine précédente" + +#. This is preceded by a colon. +#: ../tgp-utils.c:62 +#, c-format +msgid "last month" +msgstr "mois précédent" + +#. This is preceded by a colon. It refers to a point on time. +#: ../tgp-utils.c:66 +msgid "unknown" +msgstr "inconnue" + +#: ../tgp-chat.c:79 +msgid "You have already left this chat." +msgstr "Vous avez déjá quitté cette conversation." + +#: ../tgp-chat.c:122 +msgid "Subject:" +msgstr "Sujet:" + +#: ../tgp-chat.c:128 +msgid "Invite link:" +msgstr "Lien d'invitation:" + +#: ../tgp-chat.c:134 +msgid "Chat ID:" +msgstr "Chat ID:" + +#: ../tgp-chat.c:232 +msgid "Users" +msgstr "Utilisateurs" diff --git a/po/pl.po b/po/pl.po index 6506db9..afab3a8 100644 --- a/po/pl.po +++ b/po/pl.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: telegram-purple\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-10-12 18:48+0200\n" -"PO-Revision-Date: 2015-10-12 18:19+0000\n" -"Last-Translator: Piotr Drąg \n" +"POT-Creation-Date: 2015-10-19 15:06+0200\n" +"PO-Revision-Date: 2015-10-19 13:11+0000\n" +"Last-Translator: Ben Wiederhake \n" "Language-Team: Polish (http://www.transifex.com/telegram-purple-developers/telegram-purple/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -49,281 +49,256 @@ msgstr "Proszę podać tylko numery w międzynarodowym formacie numerów telefon msgid "Query Failed" msgstr "Zapytanie się nie powiodło" -#: ../telegram-purple.c:172 +#: ../telegram-purple.c:202 msgid "Secret chat terminated." msgstr "Zakończono tajną rozmowę." -#: ../telegram-purple.c:215 +#: ../telegram-purple.c:247 msgid "Message marked as read." msgstr "Oznaczono wiadomość jako przeczytaną." -#: ../telegram-purple.c:475 +#: ../telegram-purple.c:484 #, c-format msgid "Invite link: %s" msgstr "Odnośnik do zaproszenia: %s" -#: ../telegram-purple.c:498 ../telegram-purple.c:499 +#: ../telegram-purple.c:504 ../telegram-purple.c:505 msgid "Creating chat link failed" msgstr "Utworzenie odnośnika do rozmowy się nie powiodło" -#: ../telegram-purple.c:500 +#: ../telegram-purple.c:506 msgid "You need to be admin of the group to do that." msgstr "Należy być administratorem grupy, aby to zrobić." -#: ../telegram-purple.c:526 +#: ../telegram-purple.c:528 msgid "Chat joined" msgstr "Dołączono do rozmowy" -#: ../telegram-purple.c:527 +#: ../telegram-purple.c:529 msgid "Chat added to list of chat rooms." msgstr "Dodano rozmowę do listy pokojów rozmów." -#: ../telegram-purple.c:541 +#: ../telegram-purple.c:543 msgid "Start secret chat ..." msgstr "Rozpocznij tajną rozmowę…" #. Generate Public Link -#: ../telegram-purple.c:547 +#: ../telegram-purple.c:549 msgid "Invite users by link ..." msgstr "Zaproś użytkowników przez odnośnik…" #. Delete self from chat -#: ../telegram-purple.c:553 +#: ../telegram-purple.c:555 msgid "Delete and exit ..." msgstr "Usuń i wyjdź…" -#: ../telegram-purple.c:571 +#: ../telegram-purple.c:573 #, c-format msgid "" "Error, server public key not found at %s. Make sure that telegram-purple is " "installed properly." msgstr "Błąd, nie odnaleziono klucza publicznego serwera w %s. Proszę się upewnić, że wtyczka telegram-purple jest poprawnie zainstalowana." -#: ../telegram-purple.c:580 +#: ../telegram-purple.c:582 #, c-format msgid "Unable to sign on as %s: missing file %s." msgstr "Nie można zalogować jako %s: brak pliku %s." -#: ../telegram-purple.c:584 +#: ../telegram-purple.c:586 msgid "" "Make sure telegram-purple is installed properly,\n" "including the .tglpub file." msgstr "Proszę się upewnić, że wtyczka telegram-purple jest poprawnie zainstalowana,\nw tym plik „.tglpub”." -#: ../telegram-purple.c:602 +#: ../telegram-purple.c:604 #, c-format msgid "Unable to sign on as %s: phone number lacks country prefix." msgstr "Nie można zalogować jako %s: numer telefonu nie ma przedrostka kraju." -#: ../telegram-purple.c:606 +#: ../telegram-purple.c:608 msgid "" "Numbers must start with the full international\n" "prefix code, e.g. +49 for Germany." msgstr "Numery muszą zaczynać się od pełnego międzynarodowego\nprzedrostka, np. +48 dla Polski." -#: ../telegram-purple.c:750 ../telegram-purple.c:751 +#: ../telegram-purple.c:733 ../telegram-purple.c:734 msgid "Cannot invite buddy to chat" msgstr "Nie można zaprosić znajomego do rozmowy" -#: ../telegram-purple.c:752 +#: ../telegram-purple.c:735 msgid "Specified user does not exist." msgstr "Podany użytkownik nie istnieje." #. Login -#: ../telegram-purple.c:895 +#: ../telegram-purple.c:877 msgid "Password (two factor authentication)" msgstr "Hasło (uwierzytelnianie dwustopniowe)" -#: ../telegram-purple.c:901 +#: ../telegram-purple.c:883 msgid "" "Fallback SMS verification\n" "(Helps when not using Pidgin and you aren't being prompted for the code)" msgstr "Zapasowa weryfikacja przez SMS\n(Pomaga w przypadkach, kiedy nie jest używany program Pidgin i użytkownik nie jest pytany o kod)" -#: ../telegram-purple.c:909 +#: ../telegram-purple.c:891 msgid "ask" msgstr "pytanie" -#: ../telegram-purple.c:910 +#: ../telegram-purple.c:892 msgid "always" msgstr "zawsze" -#: ../telegram-purple.c:911 +#: ../telegram-purple.c:893 msgid "never" msgstr "nigdy" -#: ../telegram-purple.c:913 +#: ../telegram-purple.c:895 msgid "Accept secret chats" msgstr "Akceptowanie tajnych rozmów" -#: ../telegram-purple.c:918 +#: ../telegram-purple.c:900 msgid "Display buddies offline after (days)" msgstr "Wyświetlanie znajomych jako w trybie offline po (w dniach)" -#: ../telegram-purple.c:923 +#: ../telegram-purple.c:905 msgid "Fetch past history on first login" msgstr "Pobieranie historii podczas pierwszego logowania" -#: ../telegram-purple.c:928 +#: ../telegram-purple.c:910 msgid "" "Don't fetch history older than (days)\n" "(0 for unlimited)" msgstr "Bez pobierania historii starszej niż (w dniach)\n(0 oznacza brak ograniczenia)" #. Chats -#: ../telegram-purple.c:936 +#: ../telegram-purple.c:918 msgid "Add all group chats to buddy list" msgstr "Dodawanie wszystkich rozmów grupowych do listy znajomych" #. Read notifications -#: ../telegram-purple.c:944 +#: ../telegram-purple.c:926 msgid "Display notices of receipt" msgstr "Wyświetlanie powiadomień o odebraniu" -#: ../telegram-purple.c:949 +#: ../telegram-purple.c:931 msgid "Send notices of receipt when present" msgstr "Wysyłanie powiadomień o odebraniu podczas obecności" -#: ../tgp-2prpl.c:386 ../tgp-request.c:130 +#: ../tgp-2prpl.c:167 ../tgp-request.c:130 msgid "First name" msgstr "Imię" -#: ../tgp-2prpl.c:387 ../tgp-request.c:132 +#: ../tgp-2prpl.c:168 ../tgp-request.c:132 msgid "Last name" msgstr "Nazwisko" -#: ../tgp-2prpl.c:389 +#: ../tgp-2prpl.c:170 msgid "Name" msgstr "Nazwa" -#: ../tgp-2prpl.c:394 ../tgp-request.c:246 ../tgp-request.c:250 +#: ../tgp-2prpl.c:175 ../tgp-request.c:246 ../tgp-request.c:250 #: ../tgp-request.c:254 msgid "Username" msgstr "Nazwa użytkownika" -#: ../tgp-2prpl.c:399 +#: ../tgp-2prpl.c:180 msgid "Last seen" msgstr "Ostatnio widziany" -#: ../tgp-2prpl.c:404 +#: ../tgp-2prpl.c:185 msgid "Phone" msgstr "Telefon" -#: ../tgp-2prpl.c:417 +#: ../tgp-2prpl.c:197 msgid "Waiting for the user to get online ..." msgstr "Oczekiwanie, aż użytkownik przejdzie do trybu online…" -#: ../tgp-2prpl.c:421 +#: ../tgp-2prpl.c:201 msgid "Self destruction timer" msgstr "Czas samozniszczenia" -#: ../tgp-2prpl.c:427 +#: ../tgp-2prpl.c:207 msgid "Off" msgstr "Wyłączone" -#: ../tgp-2prpl.c:434 +#: ../tgp-2prpl.c:214 msgid "Secret key" msgstr "Tajny klucz" -#: ../tgp-msg.c:55 +#: ../tgp-msg.c:53 #, c-format msgid "%2$s created chat %1$s." msgstr "Użytkownik %2$s utworzył rozmowę %1$s." -#: ../tgp-msg.c:58 +#: ../tgp-msg.c:56 #, c-format msgid "%2$s changed title to %1$s." msgstr "Użytkownik %2$s zmienił tytuł na %1$s." -#: ../tgp-msg.c:61 +#: ../tgp-msg.c:59 #, c-format msgid "%s changed photo." msgstr "Użytkownik %s zmienił zdjęcie." -#: ../tgp-msg.c:64 +#: ../tgp-msg.c:62 #, c-format msgid "%s deleted photo." msgstr "Użytkownik %s usunął zdjęcie." -#: ../tgp-msg.c:72 +#: ../tgp-msg.c:70 #, c-format msgid "%1$s added user %2$s by link." msgstr "Użytkownik %1$s dodał użytkownika %2$s przez odnośnik." -#: ../tgp-msg.c:85 +#: ../tgp-msg.c:83 #, c-format msgid "%2$s added user %1$s." msgstr "Użytkownik %2$s dodał użytkownika %1$s." -#: ../tgp-msg.c:107 +#: ../tgp-msg.c:104 #, c-format msgid "%1$s deleted user %2$s." msgstr "Użytkownik %1$s usunął użytkownika %2$s." -#: ../tgp-msg.c:120 +#: ../tgp-msg.c:118 #, c-format msgid "%2$s deleted user %1$s." msgstr "Użytkownik %2$s usunął użytkownika %1$s." -#: ../tgp-msg.c:125 +#: ../tgp-msg.c:123 #, c-format msgid "%2$s set self destruction timer to %1$d seconds." msgstr "Użytkownik %2$s ustawił czas samozniszczenia na %1$d s." -#: ../tgp-msg.c:128 +#: ../tgp-msg.c:126 #, c-format msgid "%2$s marked %1$d messages read." msgstr "Użytkownik %2$s oznaczył %1$d wiadomości jako przeczytane." -#: ../tgp-msg.c:131 +#: ../tgp-msg.c:129 #, c-format msgid "%2$s deleted %1$d messages." msgstr "Użytkownik %2$s usunął %1$d wiadomości." -#: ../tgp-msg.c:134 +#: ../tgp-msg.c:132 #, c-format msgid "%2$s made a screenshot of %1$d messages." msgstr "Użytkownik %2$s utworzył zrzut ekranu %1$d wiadomości." -#: ../tgp-msg.c:137 -#, c-format -msgid "%2$s updated to layer %1$d." -msgstr "Użytkownik %2$s zaktualizował do warstwy %1$d." - -#: ../tgp-msg.c:140 -#, c-format -msgid "%2$s requests rekey #%1$016llx." -msgstr "Użytkownik %2$s zażądał ponownego nadania klucza #%1$016llx." - -#: ../tgp-msg.c:143 -#, c-format -msgid "%2$s accepts rekey #%1$016llx." -msgstr "Użytkownik %2$s zaakceptował ponowne nadanie klucza #%1$016llx." - -#: ../tgp-msg.c:146 -#, c-format -msgid "%2$s commits rekey #%1$016llx." -msgstr "Użytkownik %2$s zatwierdził ponowne nadanie klucza #%1$016llx." - -#: ../tgp-msg.c:149 -#, c-format -msgid "%2$s aborts rekey #%1$016llx." -msgstr "Użytkownik %2$s przerwał ponowne nadanie klucza #%1$016llx." - -#: ../tgp-msg.c:173 +#: ../tgp-msg.c:156 #, c-format msgid "Sending message failed. %d: %s" msgstr "Wysłanie wiadomości się nie powiodło. %d: %s" -#: ../tgp-msg.c:251 +#: ../tgp-msg.c:259 msgid "Sending image failed." msgstr "Wysłanie obrazu się nie powiodło." -#: ../tgp-msg.c:265 +#: ../tgp-msg.c:273 msgid "Sorry, sending documents to encrypted chats not yet supported." msgstr "Wysyłanie dokumentów do zaszyfrowanych rozmów nie jest jeszcze obsługiwane." -#: ../tgp-msg.c:352 +#: ../tgp-msg.c:360 #, c-format msgid "%s sent a sticker." msgstr "Użytkownik %s wysłał naklejkę." @@ -460,49 +435,49 @@ msgstr "Utworzyć nową rozmowę grupową o nazwie „%s”?" #. This should be the language's timestamp format. #. * This is preceded by a colon. -#: ../tgp-utils.c:39 +#: ../tgp-utils.c:33 msgid "%d.%m.%Y %H:%M" msgstr "%d.%m.%Y %H∶%M" #. This is preceded by a colon. -#: ../tgp-utils.c:60 +#: ../tgp-utils.c:54 #, c-format msgid "recently" msgstr "niedawno" #. This is preceded by a colon. -#: ../tgp-utils.c:64 +#: ../tgp-utils.c:58 #, c-format msgid "last week" msgstr "ostatni tydzień" #. This is preceded by a colon. -#: ../tgp-utils.c:68 +#: ../tgp-utils.c:62 #, c-format msgid "last month" msgstr "ostatni miesiąc" #. This is preceded by a colon. It refers to a point on time. -#: ../tgp-utils.c:72 +#: ../tgp-utils.c:66 msgid "unknown" msgstr "nieznane" -#: ../tgp-chat.c:83 +#: ../tgp-chat.c:79 msgid "You have already left this chat." msgstr "Już opuszczoną tę rozmowę." -#: ../tgp-chat.c:133 +#: ../tgp-chat.c:122 msgid "Subject:" msgstr "Temat:" -#: ../tgp-chat.c:139 +#: ../tgp-chat.c:128 msgid "Invite link:" msgstr "Odnośnik do zaproszenia:" -#: ../tgp-chat.c:145 +#: ../tgp-chat.c:134 msgid "Chat ID:" msgstr "Identyfikator rozmowy:" -#: ../tgp-chat.c:244 +#: ../tgp-chat.c:232 msgid "Users" msgstr "Użytkownicy" diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 0000000..aa25e22 --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,483 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Gilberto Coutinho , 2015 +msgid "" +msgstr "" +"Project-Id-Version: telegram-purple\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-10-19 15:06+0200\n" +"PO-Revision-Date: 2015-10-19 21:15+0000\n" +"Last-Translator: Gilberto Coutinho \n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/telegram-purple-developers/telegram-purple/language/pt_BR/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pt_BR\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: ../telegram-base.c:477 +msgid "Login canceled" +msgstr "Login cancelado" + +#: ../telegram-base.c:477 +msgid "" +"Authentication export to remote data centers failed, login not possible." +msgstr "Exportação de autenticação para servidor remoto falho, não é possível fazer o login" + +#: ../telegram-base.c:524 +msgid "Couldn't create group" +msgstr "Não foi possível criar o grupo" + +#: ../telegram-base.c:524 +msgid "Select at least one other user" +msgstr "Selecione ao menos um usuNumeroário" + +#: ../telegram-base.c:532 +msgid "Invalid phone number" +msgstr "Número de telefone inválido" + +#: ../telegram-base.c:533 +msgid "" +"Please enter only numbers in the international phone number format, a leading + following by the country prefix and the phone number.\n" +"Do not use any other special chars." +msgstr "Por favor, adicione apenas número no formato de telefeno internacional, iniciando com + seguindo pelo código do país e o número do telefone.\nNão use outros caractérers especiais." + +#: ../telegram-base.c:647 +msgid "Query Failed" +msgstr "Falha na fila" + +#: ../telegram-purple.c:202 +msgid "Secret chat terminated." +msgstr "Conversa secreta terminada." + +#: ../telegram-purple.c:247 +msgid "Message marked as read." +msgstr "Mensagem marcada como \"lida\"." + +#: ../telegram-purple.c:484 +#, c-format +msgid "Invite link: %s" +msgstr "Link de convite: %s" + +#: ../telegram-purple.c:504 ../telegram-purple.c:505 +msgid "Creating chat link failed" +msgstr "Falha na criação do link para a conversa" + +#: ../telegram-purple.c:506 +msgid "You need to be admin of the group to do that." +msgstr "Você precisa ser administrador do grupo apra fazer isso." + +#: ../telegram-purple.c:528 +msgid "Chat joined" +msgstr "Entrou na conversa" + +#: ../telegram-purple.c:529 +msgid "Chat added to list of chat rooms." +msgstr "Conversa adicionada a listas de salas de conversa" + +#: ../telegram-purple.c:543 +msgid "Start secret chat ..." +msgstr "Iniciando conversa sercreta..." + +#. Generate Public Link +#: ../telegram-purple.c:549 +msgid "Invite users by link ..." +msgstr "Convidar usuário pelo link..." + +#. Delete self from chat +#: ../telegram-purple.c:555 +msgid "Delete and exit ..." +msgstr "Deletar e sair..." + +#: ../telegram-purple.c:573 +#, c-format +msgid "" +"Error, server public key not found at %s. Make sure that telegram-purple is " +"installed properly." +msgstr "Erro, chave publica do servidor não foi encontrada em %s. Tenha certeza que o telegram-purple está instalado corretamente." + +#: ../telegram-purple.c:582 +#, c-format +msgid "Unable to sign on as %s: missing file %s." +msgstr "Não foi possível assinar como %s. falta o arquivo %s." + +#: ../telegram-purple.c:586 +msgid "" +"Make sure telegram-purple is installed properly,\n" +"including the .tglpub file." +msgstr "Tenha certeza que o telegram-purple está instalado corretamente,\nincluindo o arquivo .tglpub." + +#: ../telegram-purple.c:604 +#, c-format +msgid "Unable to sign on as %s: phone number lacks country prefix." +msgstr "Não foi possível assinar como %s: o número de telefone não está com o prefixo do país." + +#: ../telegram-purple.c:608 +msgid "" +"Numbers must start with the full international\n" +"prefix code, e.g. +49 for Germany." +msgstr "Números precisam começar com o prefixo internacional,\npor exemplo: +55 para o Brasil." + +#: ../telegram-purple.c:733 ../telegram-purple.c:734 +msgid "Cannot invite buddy to chat" +msgstr "Não foi possível convidar o amigo para a conversa" + +#: ../telegram-purple.c:735 +msgid "Specified user does not exist." +msgstr "O usuário especificado não existe." + +#. Login +#: ../telegram-purple.c:877 +msgid "Password (two factor authentication)" +msgstr "Senha (processo de autenticação dupla)" + +#: ../telegram-purple.c:883 +msgid "" +"Fallback SMS verification\n" +"(Helps when not using Pidgin and you aren't being prompted for the code)" +msgstr "Retorno de verificaçao via SMS\n(Ajuda quando não estiver usando o Pidgin e não é apresentado a janela com o código)" + +#: ../telegram-purple.c:891 +msgid "ask" +msgstr "pergunta" + +#: ../telegram-purple.c:892 +msgid "always" +msgstr "sempre" + +#: ../telegram-purple.c:893 +msgid "never" +msgstr "nunca" + +#: ../telegram-purple.c:895 +msgid "Accept secret chats" +msgstr "Aceitar conversa secrete" + +#: ../telegram-purple.c:900 +msgid "Display buddies offline after (days)" +msgstr "Mostrar período que os amigos estão offline (dias)" + +#: ../telegram-purple.c:905 +msgid "Fetch past history on first login" +msgstr "Trazer histórico no primeio login" + +#: ../telegram-purple.c:910 +msgid "" +"Don't fetch history older than (days)\n" +"(0 for unlimited)" +msgstr "Não trazer históricos mais velhos que (dias)\n(0 para não limitar)" + +#. Chats +#: ../telegram-purple.c:918 +msgid "Add all group chats to buddy list" +msgstr "Adicinar todos os grupos de conversa a lista de amigos" + +#. Read notifications +#: ../telegram-purple.c:926 +msgid "Display notices of receipt" +msgstr "Mostrar avisos de recebimento" + +#: ../telegram-purple.c:931 +msgid "Send notices of receipt when present" +msgstr "Mandar avisos de recebimento quando estiver online" + +#: ../tgp-2prpl.c:167 ../tgp-request.c:130 +msgid "First name" +msgstr "Primeiro nome" + +#: ../tgp-2prpl.c:168 ../tgp-request.c:132 +msgid "Last name" +msgstr "Último nome" + +#: ../tgp-2prpl.c:170 +msgid "Name" +msgstr "Nome" + +#: ../tgp-2prpl.c:175 ../tgp-request.c:246 ../tgp-request.c:250 +#: ../tgp-request.c:254 +msgid "Username" +msgstr "Nome de usuário" + +#: ../tgp-2prpl.c:180 +msgid "Last seen" +msgstr "Visto em" + +#: ../tgp-2prpl.c:185 +msgid "Phone" +msgstr "Fone" + +#: ../tgp-2prpl.c:197 +msgid "Waiting for the user to get online ..." +msgstr "Esperando pelo usuário ficar onlie" + +#: ../tgp-2prpl.c:201 +msgid "Self destruction timer" +msgstr "Tempo para auto destruição" + +#: ../tgp-2prpl.c:207 +msgid "Off" +msgstr "Desligado" + +#: ../tgp-2prpl.c:214 +msgid "Secret key" +msgstr "Chave secreta" + +#: ../tgp-msg.c:53 +#, c-format +msgid "%2$s created chat %1$s." +msgstr "%2$s criouo a conversa %1$s." + +#: ../tgp-msg.c:56 +#, c-format +msgid "%2$s changed title to %1$s." +msgstr "%2$s mudou o assunto para %1$s," + +#: ../tgp-msg.c:59 +#, c-format +msgid "%s changed photo." +msgstr "%s mudou a foto." + +#: ../tgp-msg.c:62 +#, c-format +msgid "%s deleted photo." +msgstr "%s deletou a foto." + +#: ../tgp-msg.c:70 +#, c-format +msgid "%1$s added user %2$s by link." +msgstr "%1$s adicionou o usuário %2$s por link." + +#: ../tgp-msg.c:83 +#, c-format +msgid "%2$s added user %1$s." +msgstr "%2$s adicionou o usuário %1$s." + +#: ../tgp-msg.c:104 +#, c-format +msgid "%1$s deleted user %2$s." +msgstr "%1$s removeu o usuário %2$s" + +#: ../tgp-msg.c:118 +#, c-format +msgid "%2$s deleted user %1$s." +msgstr "%2$s reoveu o usuário %1$s" + +#: ../tgp-msg.c:123 +#, c-format +msgid "%2$s set self destruction timer to %1$d seconds." +msgstr "%2$s tempo para auto destruição configurado para %1$d segundos." + +#: ../tgp-msg.c:126 +#, c-format +msgid "%2$s marked %1$d messages read." +msgstr "%2$s marcou %1$d mensagens como lidas." + +#: ../tgp-msg.c:129 +#, c-format +msgid "%2$s deleted %1$d messages." +msgstr "%2$s deletou %1$d mensagens." + +#: ../tgp-msg.c:132 +#, c-format +msgid "%2$s made a screenshot of %1$d messages." +msgstr "%2$s capturou a tela de %1$d mesnagens." + +#: ../tgp-msg.c:156 +#, c-format +msgid "Sending message failed. %d: %s" +msgstr "Envio da mensagem falhou. %d: %s." + +#: ../tgp-msg.c:259 +msgid "Sending image failed." +msgstr "Envio de imagem falhou." + +#: ../tgp-msg.c:273 +msgid "Sorry, sending documents to encrypted chats not yet supported." +msgstr "Desculpe, envio de documentos para conversas encriptadas não é suportado." + +#: ../tgp-msg.c:360 +#, c-format +msgid "%s sent a sticker." +msgstr "%s enviou um adesivo." + +#: ../tgp-net.c:326 +msgid "Cannot connect to server" +msgstr "Não pode se conectar no servidor" + +#: ../tgp-net.c:371 +msgid "Lost connection to the server ..." +msgstr "Perdeu a conexão com o servidor..." + +#: ../tgp-request.c:76 ../tgp-request.c:137 +msgid "Login code" +msgstr "Código de login" + +#: ../tgp-request.c:76 +msgid "Enter login code" +msgstr "Insira o código de login" + +#: ../tgp-request.c:76 +msgid "" +"Telegram wants to verify your identity. Please enter the code that you have " +"received via SMS." +msgstr "Telegram quer confirmar sua identidade. Por favor insira o código recebido por SMS." + +#: ../tgp-request.c:77 +msgid "the code" +msgstr "o código" + +#: ../tgp-request.c:77 ../tgp-request.c:141 ../tgp-request.c:259 +msgid "OK" +msgstr "OK" + +#: ../tgp-request.c:78 ../tgp-request.c:142 ../tgp-request.c:260 +msgid "Cancel" +msgstr "Cancelar" + +#: ../tgp-request.c:85 +msgid "What is your SMS verification code?" +msgstr "Qual seu código de verificação SMS?" + +#: ../tgp-request.c:129 +msgid "Registration" +msgstr "Registro" + +#: ../tgp-request.c:136 +msgid "Authorization" +msgstr "Autorização" + +#: ../tgp-request.c:141 +msgid "Register" +msgstr "Registrar" + +#: ../tgp-request.c:141 +msgid "Please register your phone number." +msgstr "Por favor registre seu número de telefone." + +#. purple_request API not available +#: ../tgp-request.c:144 +msgid "" +"Phone number is not registered. Please register your phone on a different " +"client." +msgstr "Número de telefone não registrado. Por favor registre seu número de telefone com um cliente diferente." + +#: ../tgp-request.c:146 +msgid "Not Registered" +msgstr "Não Registrado" + +#: ../tgp-request.c:169 +msgid "Password" +msgstr "Senha" + +#: ../tgp-request.c:174 +msgid "Enter password" +msgstr "Insira a senha" + +#: ../tgp-request.c:174 +msgid "Enter password for two factor authentication" +msgstr "Insira a senha para o processo de autenticação dupla" + +#: ../tgp-request.c:177 +msgid "" +"No password set for two factor authentication. Please enter it in the " +"extended settings." +msgstr "Não há senha configurado para o processo de autenticação dupla. Por favor insira nas configurações expandidas." + +#: ../tgp-request.c:179 +msgid "Password invalid" +msgstr "Senha inválida" + +#: ../tgp-request.c:207 +#, c-format +msgid "Accept Secret Chat '%s'?" +msgstr "Aceitar Conversa Secreta '%s'?" + +#: ../tgp-request.c:208 +msgid "Secret Chat" +msgstr "Conversa Secreta" + +#: ../tgp-request.c:208 +msgid "" +"Secret chats can only have one end point. If you accept a secret chat on " +"this device, its messages will not be available anywhere else. If you " +"decline, you can accept the chat on other devices." +msgstr "Conversas secretas podem ocorrer em apenas um loca. Se você aceitar uma conversa secreta nesse dispositivo, essas mensagens não estarão disponíveis em nenhum outro local. Se você rejeitar, pode aceitar a conversa em outros dispositivos." + +#: ../tgp-request.c:243 +msgid "" +"Invite at least one additional user (Autocompletion available).\n" +"You can add more users once the chat was created." +msgstr "Convide ao menos um usuário a mais (Autocompletar disponível).\nVocê pode adicionar mais usuários depois que a conversa estiver criada." + +#. FIXME: This dialog is pointless. It only asks whether the user wants to +#. create a new chat. +#. This should be merged with the next dialog. +#. TODO: This still displays "Cancel" and "Accept", no matter $LANG +#: ../tgp-request.c:259 ../tgp-request.c:275 +msgid "Create group chat" +msgstr "Criar conversa em grupo" + +#: ../tgp-request.c:259 +msgid "Invite users" +msgstr "Convidar usuários" + +#: ../tgp-request.c:269 +msgid "Chat doesn't exist (yet)" +msgstr "Conversa não existe (ainda)" + +#: ../tgp-request.c:270 +#, c-format +msgid "Do you want to create a new group chat named '%s'?" +msgstr "Você quer criar uma nova conversa em grupo chamada '%s'?" + +#. This should be the language's timestamp format. +#. * This is preceded by a colon. +#: ../tgp-utils.c:33 +msgid "%d.%m.%Y %H:%M" +msgstr "%d.%m.%Y %H:%M" + +#. This is preceded by a colon. +#: ../tgp-utils.c:54 +#, c-format +msgid "recently" +msgstr "recentemente" + +#. This is preceded by a colon. +#: ../tgp-utils.c:58 +#, c-format +msgid "last week" +msgstr "semana passada" + +#. This is preceded by a colon. +#: ../tgp-utils.c:62 +#, c-format +msgid "last month" +msgstr "mês passado" + +#. This is preceded by a colon. It refers to a point on time. +#: ../tgp-utils.c:66 +msgid "unknown" +msgstr "desconhecido" + +#: ../tgp-chat.c:79 +msgid "You have already left this chat." +msgstr "Você já saiu dessa conversa." + +#: ../tgp-chat.c:122 +msgid "Subject:" +msgstr "Assunto:" + +#: ../tgp-chat.c:128 +msgid "Invite link:" +msgstr "Link do convite:" + +#: ../tgp-chat.c:134 +msgid "Chat ID:" +msgstr "Identificação da conversa:" + +#: ../tgp-chat.c:232 +msgid "Users" +msgstr "Usuários" diff --git a/po/ru.po b/po/ru.po index 4051042..e02ec6f 100644 --- a/po/ru.po +++ b/po/ru.po @@ -3,13 +3,15 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Vladimir , 2015 +# Yan Pas, 2015 # Сергей , 2015 msgid "" msgstr "" "Project-Id-Version: telegram-purple\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-10-12 18:48+0200\n" -"PO-Revision-Date: 2015-10-12 16:49+0000\n" +"POT-Creation-Date: 2015-10-19 15:06+0200\n" +"PO-Revision-Date: 2015-10-19 13:11+0000\n" "Last-Translator: Ben Wiederhake \n" "Language-Team: Russian (http://www.transifex.com/telegram-purple-developers/telegram-purple/language/ru/)\n" "MIME-Version: 1.0\n" @@ -20,12 +22,12 @@ msgstr "" #: ../telegram-base.c:477 msgid "Login canceled" -msgstr "" +msgstr "Вход отменен" #: ../telegram-base.c:477 msgid "" "Authentication export to remote data centers failed, login not possible." -msgstr "" +msgstr "Экспорт аутентификации на удаленные дата-центры не удался. Авторизация невозможна." #: ../telegram-base.c:524 msgid "Couldn't create group" @@ -33,7 +35,7 @@ msgstr "Не удалось создать группу" #: ../telegram-base.c:524 msgid "Select at least one other user" -msgstr "" +msgstr "Выберите хотя бы одного другого пользователя" #: ../telegram-base.c:532 msgid "Invalid phone number" @@ -43,290 +45,265 @@ msgstr "Неправильный номер телефона" msgid "" "Please enter only numbers in the international phone number format, a leading + following by the country prefix and the phone number.\n" "Do not use any other special chars." -msgstr "" +msgstr "Пожалуйста, введите только номер в международном формате телефонного номера. Начиная с +, префикса страны и телефонного номера. Не используйте никакие другие специальные символы." #: ../telegram-base.c:647 msgid "Query Failed" msgstr "Ошибка запроса" -#: ../telegram-purple.c:172 +#: ../telegram-purple.c:202 msgid "Secret chat terminated." msgstr "Защищенный чат завершен" -#: ../telegram-purple.c:215 +#: ../telegram-purple.c:247 msgid "Message marked as read." msgstr "Сообщение помечено как прочитанное" -#: ../telegram-purple.c:475 +#: ../telegram-purple.c:484 #, c-format msgid "Invite link: %s" -msgstr "" +msgstr "Пригласительная ссылка: %s" -#: ../telegram-purple.c:498 ../telegram-purple.c:499 +#: ../telegram-purple.c:504 ../telegram-purple.c:505 msgid "Creating chat link failed" -msgstr "" +msgstr "Не удалось создать ссылку чата" -#: ../telegram-purple.c:500 +#: ../telegram-purple.c:506 msgid "You need to be admin of the group to do that." -msgstr "" +msgstr "Вы должны быть администратором группы, чтобы сделать это." -#: ../telegram-purple.c:526 +#: ../telegram-purple.c:528 msgid "Chat joined" msgstr "Присоединился к чату" -#: ../telegram-purple.c:527 +#: ../telegram-purple.c:529 msgid "Chat added to list of chat rooms." -msgstr "" +msgstr "Чат добавлен в список чатов." -#: ../telegram-purple.c:541 +#: ../telegram-purple.c:543 msgid "Start secret chat ..." msgstr "Начать защищенный чат..." #. Generate Public Link -#: ../telegram-purple.c:547 +#: ../telegram-purple.c:549 msgid "Invite users by link ..." -msgstr "" +msgstr "Пригласить пользователей по ссылке ..." #. Delete self from chat -#: ../telegram-purple.c:553 +#: ../telegram-purple.c:555 msgid "Delete and exit ..." msgstr "Удалить и выйти..." -#: ../telegram-purple.c:571 +#: ../telegram-purple.c:573 #, c-format msgid "" "Error, server public key not found at %s. Make sure that telegram-purple is " "installed properly." -msgstr "" +msgstr "Ошибка. Публичный ключ сервера не найден в %s. Убедитесь, что telegram-purple установлен правильно." -#: ../telegram-purple.c:580 +#: ../telegram-purple.c:582 #, c-format msgid "Unable to sign on as %s: missing file %s." -msgstr "" +msgstr "Не удается войти как %s: не найден файл %s." -#: ../telegram-purple.c:584 +#: ../telegram-purple.c:586 msgid "" "Make sure telegram-purple is installed properly,\n" "including the .tglpub file." -msgstr "" +msgstr "Убедитесь, что telegram-purple установлен правильно,\nвключая файл .tglpub." -#: ../telegram-purple.c:602 +#: ../telegram-purple.c:604 #, c-format msgid "Unable to sign on as %s: phone number lacks country prefix." -msgstr "" +msgstr "Не удается войти как %s: номер телефона не имеет кода страны." -#: ../telegram-purple.c:606 +#: ../telegram-purple.c:608 msgid "" "Numbers must start with the full international\n" "prefix code, e.g. +49 for Germany." msgstr "Номер должен начинаться с международного \nпрефикса, например +7 для России." -#: ../telegram-purple.c:750 ../telegram-purple.c:751 +#: ../telegram-purple.c:733 ../telegram-purple.c:734 msgid "Cannot invite buddy to chat" msgstr "Не могу пригласить пользователя в чат" -#: ../telegram-purple.c:752 +#: ../telegram-purple.c:735 msgid "Specified user does not exist." msgstr "Указанный пользователь не существует." #. Login -#: ../telegram-purple.c:895 +#: ../telegram-purple.c:877 msgid "Password (two factor authentication)" msgstr "Пароль (двухфакторная аутентификация) " -#: ../telegram-purple.c:901 +#: ../telegram-purple.c:883 msgid "" "Fallback SMS verification\n" "(Helps when not using Pidgin and you aren't being prompted for the code)" -msgstr "" +msgstr "Альтернативная СМС верификация\n(Помогает когда не используется pidgin и вас не просило ввести код)" -#: ../telegram-purple.c:909 +#: ../telegram-purple.c:891 msgid "ask" -msgstr "" +msgstr "Спрашивать" -#: ../telegram-purple.c:910 +#: ../telegram-purple.c:892 msgid "always" msgstr "всегда" -#: ../telegram-purple.c:911 +#: ../telegram-purple.c:893 msgid "never" msgstr "никогда" -#: ../telegram-purple.c:913 +#: ../telegram-purple.c:895 msgid "Accept secret chats" msgstr "Присоединится к защищенным чатам" -#: ../telegram-purple.c:918 +#: ../telegram-purple.c:900 msgid "Display buddies offline after (days)" -msgstr "" +msgstr "Показывать друзей оффлайн через(дней)" -#: ../telegram-purple.c:923 +#: ../telegram-purple.c:905 msgid "Fetch past history on first login" msgstr "Загрузить историю при первом входе" -#: ../telegram-purple.c:928 +#: ../telegram-purple.c:910 msgid "" "Don't fetch history older than (days)\n" "(0 for unlimited)" msgstr "Не загружать историю старше N дней\n(0 без ограничений)" #. Chats -#: ../telegram-purple.c:936 +#: ../telegram-purple.c:918 msgid "Add all group chats to buddy list" msgstr "Добавить все групповые чаты в контактлист" #. Read notifications -#: ../telegram-purple.c:944 +#: ../telegram-purple.c:926 msgid "Display notices of receipt" msgstr "Показать уведомления о получении" -#: ../telegram-purple.c:949 +#: ../telegram-purple.c:931 msgid "Send notices of receipt when present" -msgstr "" +msgstr "Показать уведомления о получении" -#: ../tgp-2prpl.c:386 ../tgp-request.c:130 +#: ../tgp-2prpl.c:167 ../tgp-request.c:130 msgid "First name" msgstr "Имя" -#: ../tgp-2prpl.c:387 ../tgp-request.c:132 +#: ../tgp-2prpl.c:168 ../tgp-request.c:132 msgid "Last name" msgstr "Фамилия" -#: ../tgp-2prpl.c:389 +#: ../tgp-2prpl.c:170 msgid "Name" msgstr "Ник" -#: ../tgp-2prpl.c:394 ../tgp-request.c:246 ../tgp-request.c:250 +#: ../tgp-2prpl.c:175 ../tgp-request.c:246 ../tgp-request.c:250 #: ../tgp-request.c:254 msgid "Username" msgstr "Пользователь" -#: ../tgp-2prpl.c:399 +#: ../tgp-2prpl.c:180 msgid "Last seen" -msgstr "" +msgstr "Последний раз был в сети" -#: ../tgp-2prpl.c:404 +#: ../tgp-2prpl.c:185 msgid "Phone" msgstr "Телефон" -#: ../tgp-2prpl.c:417 +#: ../tgp-2prpl.c:197 msgid "Waiting for the user to get online ..." -msgstr "" +msgstr "Ожидание пользователя ..." -#: ../tgp-2prpl.c:421 +#: ../tgp-2prpl.c:201 msgid "Self destruction timer" -msgstr "" +msgstr "Таймер самоуничтожения" -#: ../tgp-2prpl.c:427 +#: ../tgp-2prpl.c:207 msgid "Off" msgstr "Выключить" -#: ../tgp-2prpl.c:434 +#: ../tgp-2prpl.c:214 msgid "Secret key" msgstr "Секретный ключ" -#: ../tgp-msg.c:55 +#: ../tgp-msg.c:53 #, c-format msgid "%2$s created chat %1$s." -msgstr "" +msgstr "%2$s создан чат %1$s." -#: ../tgp-msg.c:58 +#: ../tgp-msg.c:56 #, c-format msgid "%2$s changed title to %1$s." -msgstr "" +msgstr "%2$s название изменено на %1$s." -#: ../tgp-msg.c:61 +#: ../tgp-msg.c:59 #, c-format msgid "%s changed photo." -msgstr "" +msgstr "%s фото изменено." -#: ../tgp-msg.c:64 +#: ../tgp-msg.c:62 #, c-format msgid "%s deleted photo." -msgstr "" +msgstr "%s фото удалено." -#: ../tgp-msg.c:72 +#: ../tgp-msg.c:70 #, c-format msgid "%1$s added user %2$s by link." -msgstr "" +msgstr "%1$s пользователи добавлены %2$s по ссылке" -#: ../tgp-msg.c:85 +#: ../tgp-msg.c:83 #, c-format msgid "%2$s added user %1$s." -msgstr "" +msgstr "%2$s пользователь добавлен %1$s." -#: ../tgp-msg.c:107 +#: ../tgp-msg.c:104 #, c-format msgid "%1$s deleted user %2$s." msgstr "%1$s пользователи удалены %2$s." -#: ../tgp-msg.c:120 +#: ../tgp-msg.c:118 #, c-format msgid "%2$s deleted user %1$s." -msgstr "" +msgstr "%2$s пользователи удалены %1$s." -#: ../tgp-msg.c:125 +#: ../tgp-msg.c:123 #, c-format msgid "%2$s set self destruction timer to %1$d seconds." -msgstr "" +msgstr "%2$s установлен таймер самоуничтожения на %1$d секунд." -#: ../tgp-msg.c:128 +#: ../tgp-msg.c:126 #, c-format msgid "%2$s marked %1$d messages read." -msgstr "" +msgstr "%2$s пометил %1$d сообщений прочитанными." -#: ../tgp-msg.c:131 +#: ../tgp-msg.c:129 #, c-format msgid "%2$s deleted %1$d messages." -msgstr "" +msgstr "%2$s удалено %1$d сообщений." -#: ../tgp-msg.c:134 +#: ../tgp-msg.c:132 #, c-format msgid "%2$s made a screenshot of %1$d messages." -msgstr "" +msgstr "%2$s сделан скриншот %1$d сообщений." -#: ../tgp-msg.c:137 -#, c-format -msgid "%2$s updated to layer %1$d." -msgstr "" - -#: ../tgp-msg.c:140 -#, c-format -msgid "%2$s requests rekey #%1$016llx." -msgstr "" - -#: ../tgp-msg.c:143 -#, c-format -msgid "%2$s accepts rekey #%1$016llx." -msgstr "" - -#: ../tgp-msg.c:146 -#, c-format -msgid "%2$s commits rekey #%1$016llx." -msgstr "" - -#: ../tgp-msg.c:149 -#, c-format -msgid "%2$s aborts rekey #%1$016llx." -msgstr "" - -#: ../tgp-msg.c:173 +#: ../tgp-msg.c:156 #, c-format msgid "Sending message failed. %d: %s" msgstr "Ошибка при отправке сообщения. %d: %s" -#: ../tgp-msg.c:251 +#: ../tgp-msg.c:259 msgid "Sending image failed." msgstr "Ошибка при отправке изображения." -#: ../tgp-msg.c:265 +#: ../tgp-msg.c:273 msgid "Sorry, sending documents to encrypted chats not yet supported." -msgstr "" +msgstr "Извините, отправка документов в секретных чатах пока не поддерживается." -#: ../tgp-msg.c:352 +#: ../tgp-msg.c:360 #, c-format msgid "%s sent a sticker." -msgstr "" +msgstr "%s отправил стикер." #: ../tgp-net.c:326 msgid "Cannot connect to server" @@ -338,21 +315,21 @@ msgstr "Потеряно соединение с сервером..." #: ../tgp-request.c:76 ../tgp-request.c:137 msgid "Login code" -msgstr "" +msgstr "Код входа" #: ../tgp-request.c:76 msgid "Enter login code" -msgstr "" +msgstr "Введите код входа" #: ../tgp-request.c:76 msgid "" "Telegram wants to verify your identity. Please enter the code that you have " "received via SMS." -msgstr "" +msgstr "Telegram хочет проверить вашу личность. Пожалуйста введите код, полученный вами через СМС." #: ../tgp-request.c:77 msgid "the code" -msgstr "" +msgstr "код" #: ../tgp-request.c:77 ../tgp-request.c:141 ../tgp-request.c:259 msgid "OK" @@ -364,7 +341,7 @@ msgstr "Отмена" #: ../tgp-request.c:85 msgid "What is your SMS verification code?" -msgstr "" +msgstr "Какой код подтверждения пришел вам по SMS?" #: ../tgp-request.c:129 msgid "Registration" @@ -387,7 +364,7 @@ msgstr "Пожалуйста, зарегистрируйте свой номер msgid "" "Phone number is not registered. Please register your phone on a different " "client." -msgstr "" +msgstr "Номер телефона не зарегистрирован. Пожалуйста зарегистрируйте ваш телефон в другом клиенте." #: ../tgp-request.c:146 msgid "Not Registered" @@ -399,17 +376,17 @@ msgstr "Пароль" #: ../tgp-request.c:174 msgid "Enter password" -msgstr "" +msgstr "Введите пароль" #: ../tgp-request.c:174 msgid "Enter password for two factor authentication" -msgstr "" +msgstr "Введите пароль для двухфакторной аутентификации" #: ../tgp-request.c:177 msgid "" "No password set for two factor authentication. Please enter it in the " "extended settings." -msgstr "" +msgstr "Не указан пароль для двухфакторной аутентификации. Пожалуйста введите его в расширенных настройках." #: ../tgp-request.c:179 msgid "Password invalid" @@ -418,7 +395,7 @@ msgstr "Неверный пароль" #: ../tgp-request.c:207 #, c-format msgid "Accept Secret Chat '%s'?" -msgstr "" +msgstr "Присоединится к защищенному чату '%s'?" #: ../tgp-request.c:208 msgid "Secret Chat" @@ -429,13 +406,13 @@ msgid "" "Secret chats can only have one end point. If you accept a secret chat on " "this device, its messages will not be available anywhere else. If you " "decline, you can accept the chat on other devices." -msgstr "" +msgstr "Секретные чаты могут иметь только одну конечную точку: если вы подтвердите секретный чат на этом устройстве, его сообщения будут недоступны нигде больше. Если вы отклоните, то вы сможете принять этот чат на других устройствах." #: ../tgp-request.c:243 msgid "" "Invite at least one additional user (Autocompletion available).\n" "You can add more users once the chat was created." -msgstr "" +msgstr "Пригласите хотя бы одного дополнительного пользователя(Автодополнение доступно).\nВы можете добавить больше пользователей после создания чата." #. FIXME: This dialog is pointless. It only asks whether the user wants to #. create a new chat. @@ -456,53 +433,53 @@ msgstr "Чат не существует" #: ../tgp-request.c:270 #, c-format msgid "Do you want to create a new group chat named '%s'?" -msgstr "" +msgstr "Вы хотите создать новый групповой чат '%s'?" #. This should be the language's timestamp format. #. * This is preceded by a colon. -#: ../tgp-utils.c:39 +#: ../tgp-utils.c:33 msgid "%d.%m.%Y %H:%M" msgstr "%d.%m.%Y %H:%M" #. This is preceded by a colon. -#: ../tgp-utils.c:60 +#: ../tgp-utils.c:54 #, c-format msgid "recently" msgstr "недавно" #. This is preceded by a colon. -#: ../tgp-utils.c:64 +#: ../tgp-utils.c:58 #, c-format msgid "last week" msgstr "последняя неделя" #. This is preceded by a colon. -#: ../tgp-utils.c:68 +#: ../tgp-utils.c:62 #, c-format msgid "last month" msgstr "последний месяц" #. This is preceded by a colon. It refers to a point on time. -#: ../tgp-utils.c:72 +#: ../tgp-utils.c:66 msgid "unknown" msgstr "неизвестно" -#: ../tgp-chat.c:83 +#: ../tgp-chat.c:79 msgid "You have already left this chat." -msgstr "" +msgstr "Вы уже покинули этот чат." -#: ../tgp-chat.c:133 +#: ../tgp-chat.c:122 msgid "Subject:" msgstr "Заголовок:" -#: ../tgp-chat.c:139 +#: ../tgp-chat.c:128 msgid "Invite link:" -msgstr "" +msgstr "Пригласительная ссылка:" -#: ../tgp-chat.c:145 +#: ../tgp-chat.c:134 msgid "Chat ID:" msgstr "Чат ID:" -#: ../tgp-chat.c:244 +#: ../tgp-chat.c:232 msgid "Users" msgstr "Пользователи" diff --git a/po/sq.po b/po/sq.po index b16fb51..34f4286 100644 --- a/po/sq.po +++ b/po/sq.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: telegram-purple\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-10-12 18:48+0200\n" -"PO-Revision-Date: 2015-10-13 07:39+0000\n" -"Last-Translator: Besnik \n" +"POT-Creation-Date: 2015-10-19 15:06+0200\n" +"PO-Revision-Date: 2015-10-19 13:11+0000\n" +"Last-Translator: Ben Wiederhake \n" "Language-Team: Albanian (http://www.transifex.com/telegram-purple-developers/telegram-purple/language/sq/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -49,281 +49,256 @@ msgstr "Ju lutemi, jepni vetëm numra sipas formatit ndërkombëtar për numra t msgid "Query Failed" msgstr "Kërkesa Dështoi" -#: ../telegram-purple.c:172 +#: ../telegram-purple.c:202 msgid "Secret chat terminated." msgstr "Fjalosja e fshehtë përfundoi." -#: ../telegram-purple.c:215 +#: ../telegram-purple.c:247 msgid "Message marked as read." msgstr "Mesazh i shënuar si i lexuar." -#: ../telegram-purple.c:475 +#: ../telegram-purple.c:484 #, c-format msgid "Invite link: %s" msgstr "Lidhje ftese: %s" -#: ../telegram-purple.c:498 ../telegram-purple.c:499 +#: ../telegram-purple.c:504 ../telegram-purple.c:505 msgid "Creating chat link failed" msgstr "Krijimi i lidhjes së fjalosjes dështoi" -#: ../telegram-purple.c:500 +#: ../telegram-purple.c:506 msgid "You need to be admin of the group to do that." msgstr "Lypset të jeni përgjegjës grupi që të bëni këtë." -#: ../telegram-purple.c:526 +#: ../telegram-purple.c:528 msgid "Chat joined" msgstr "U hy në fjalosje" -#: ../telegram-purple.c:527 +#: ../telegram-purple.c:529 msgid "Chat added to list of chat rooms." msgstr "Fjalosja u shtua te listë dhomash fjalosjeje." -#: ../telegram-purple.c:541 +#: ../telegram-purple.c:543 msgid "Start secret chat ..." msgstr "Filloni fjalosje të fshehtë ..." #. Generate Public Link -#: ../telegram-purple.c:547 +#: ../telegram-purple.c:549 msgid "Invite users by link ..." msgstr "Ftoni përdorues me lidhje ..." #. Delete self from chat -#: ../telegram-purple.c:553 +#: ../telegram-purple.c:555 msgid "Delete and exit ..." msgstr "Fshije dhe dil ..." -#: ../telegram-purple.c:571 +#: ../telegram-purple.c:573 #, c-format msgid "" "Error, server public key not found at %s. Make sure that telegram-purple is " "installed properly." msgstr "Gabim, s’u gjet kyç publik shërbyesi te %s. Sigurohuni që telegram-purple është instaluar si duhet." -#: ../telegram-purple.c:580 +#: ../telegram-purple.c:582 #, c-format msgid "Unable to sign on as %s: missing file %s." msgstr "Nuk arrihet të bëhet hyrja si %s: mungon kartela %s." -#: ../telegram-purple.c:584 +#: ../telegram-purple.c:586 msgid "" "Make sure telegram-purple is installed properly,\n" "including the .tglpub file." msgstr "Sigurohuni që telegram-purple është instaluar si duhet,\npërfshi kartelën .tglpub." -#: ../telegram-purple.c:602 +#: ../telegram-purple.c:604 #, c-format msgid "Unable to sign on as %s: phone number lacks country prefix." msgstr "Nuk arrihet të bëhet hyrja si %s: numrit të telefonit i mungon prefiksi i vendit." -#: ../telegram-purple.c:606 +#: ../telegram-purple.c:608 msgid "" "Numbers must start with the full international\n" "prefix code, e.g. +49 for Germany." msgstr "Numrat duhet të fillojnë me kodin e plotë prefiks\nndërkombëtar, p.sh. +355 për Shqipërinë." -#: ../telegram-purple.c:750 ../telegram-purple.c:751 +#: ../telegram-purple.c:733 ../telegram-purple.c:734 msgid "Cannot invite buddy to chat" msgstr "S’ftohet dot shok në fjalosje" -#: ../telegram-purple.c:752 +#: ../telegram-purple.c:735 msgid "Specified user does not exist." msgstr "Përdoruesi i treguar nuk ekziston." #. Login -#: ../telegram-purple.c:895 +#: ../telegram-purple.c:877 msgid "Password (two factor authentication)" msgstr "Fjalëkalim (mirëfilltësim dyfaktorësh)" -#: ../telegram-purple.c:901 +#: ../telegram-purple.c:883 msgid "" "Fallback SMS verification\n" "(Helps when not using Pidgin and you aren't being prompted for the code)" msgstr "Kalim vetvetiu për verfikime SMS\n(I dobishëm kur s’përdoret Pidgin-i dhe nuk ju kërkohet kod)" -#: ../telegram-purple.c:909 +#: ../telegram-purple.c:891 msgid "ask" msgstr "pyet" -#: ../telegram-purple.c:910 +#: ../telegram-purple.c:892 msgid "always" msgstr "përherë" -#: ../telegram-purple.c:911 +#: ../telegram-purple.c:893 msgid "never" msgstr "kurrë" -#: ../telegram-purple.c:913 +#: ../telegram-purple.c:895 msgid "Accept secret chats" msgstr "Prano fjalosje të fshehta" -#: ../telegram-purple.c:918 +#: ../telegram-purple.c:900 msgid "Display buddies offline after (days)" msgstr "Shfaqi shokët si jo të lidhur pas (ditësh)" -#: ../telegram-purple.c:923 +#: ../telegram-purple.c:905 msgid "Fetch past history on first login" msgstr "Sill historik të kaluar gjatë hyrjes së parë" -#: ../telegram-purple.c:928 +#: ../telegram-purple.c:910 msgid "" "Don't fetch history older than (days)\n" "(0 for unlimited)" msgstr "Mos sill historik më të vjetë se (ditë)\n(0 për pa kufizim)" #. Chats -#: ../telegram-purple.c:936 +#: ../telegram-purple.c:918 msgid "Add all group chats to buddy list" msgstr "Shtoji krejt fjalosjet e grupit te lista e shokëve" #. Read notifications -#: ../telegram-purple.c:944 +#: ../telegram-purple.c:926 msgid "Display notices of receipt" msgstr "Shfaq njoftime dëftese" -#: ../telegram-purple.c:949 +#: ../telegram-purple.c:931 msgid "Send notices of receipt when present" msgstr "Dërgo njoftime dëftese kur ka" -#: ../tgp-2prpl.c:386 ../tgp-request.c:130 +#: ../tgp-2prpl.c:167 ../tgp-request.c:130 msgid "First name" msgstr "Emër" -#: ../tgp-2prpl.c:387 ../tgp-request.c:132 +#: ../tgp-2prpl.c:168 ../tgp-request.c:132 msgid "Last name" msgstr "Mbiemër" -#: ../tgp-2prpl.c:389 +#: ../tgp-2prpl.c:170 msgid "Name" msgstr "Emër" -#: ../tgp-2prpl.c:394 ../tgp-request.c:246 ../tgp-request.c:250 +#: ../tgp-2prpl.c:175 ../tgp-request.c:246 ../tgp-request.c:250 #: ../tgp-request.c:254 msgid "Username" msgstr "Emër përdoruesi" -#: ../tgp-2prpl.c:399 +#: ../tgp-2prpl.c:180 msgid "Last seen" msgstr "Parë së fundi" -#: ../tgp-2prpl.c:404 +#: ../tgp-2prpl.c:185 msgid "Phone" msgstr "Telefon" -#: ../tgp-2prpl.c:417 +#: ../tgp-2prpl.c:197 msgid "Waiting for the user to get online ..." msgstr "Po pritet që përdoruesi të lidhet në internet ..." -#: ../tgp-2prpl.c:421 +#: ../tgp-2prpl.c:201 msgid "Self destruction timer" msgstr "Kohëmatës vetëshkatërrimi" -#: ../tgp-2prpl.c:427 +#: ../tgp-2prpl.c:207 msgid "Off" msgstr "Off" -#: ../tgp-2prpl.c:434 +#: ../tgp-2prpl.c:214 msgid "Secret key" msgstr "Kyç i fshehtë" -#: ../tgp-msg.c:55 +#: ../tgp-msg.c:53 #, c-format msgid "%2$s created chat %1$s." msgstr "%2$s krijoi fjalosjen %1$s." -#: ../tgp-msg.c:58 +#: ../tgp-msg.c:56 #, c-format msgid "%2$s changed title to %1$s." msgstr "%2$s ndryshoi titullin te %1$s." -#: ../tgp-msg.c:61 +#: ../tgp-msg.c:59 #, c-format msgid "%s changed photo." msgstr "%s ndryshoi foton." -#: ../tgp-msg.c:64 +#: ../tgp-msg.c:62 #, c-format msgid "%s deleted photo." msgstr "%s fshiu foton." -#: ../tgp-msg.c:72 +#: ../tgp-msg.c:70 #, c-format msgid "%1$s added user %2$s by link." msgstr "%1$s shtoi përdoruesin %2$s përmes lidhjeje." -#: ../tgp-msg.c:85 +#: ../tgp-msg.c:83 #, c-format msgid "%2$s added user %1$s." msgstr "%2$s shtoi përdoruesin %1$s." -#: ../tgp-msg.c:107 +#: ../tgp-msg.c:104 #, c-format msgid "%1$s deleted user %2$s." msgstr "%1$s fshiu përdoruesin %2$s." -#: ../tgp-msg.c:120 +#: ../tgp-msg.c:118 #, c-format msgid "%2$s deleted user %1$s." msgstr "%2$s fshiu përdoruesin %1$s." -#: ../tgp-msg.c:125 +#: ../tgp-msg.c:123 #, c-format msgid "%2$s set self destruction timer to %1$d seconds." msgstr "%2$s e vendosi kohëmatësin e vetëshkatërrimit në %1$d sekonda." -#: ../tgp-msg.c:128 +#: ../tgp-msg.c:126 #, c-format msgid "%2$s marked %1$d messages read." msgstr "%2$s shënoi %1$d mesazhe si të lexuar." -#: ../tgp-msg.c:131 +#: ../tgp-msg.c:129 #, c-format msgid "%2$s deleted %1$d messages." msgstr "%2$s fshiu %1$d mesazhe." -#: ../tgp-msg.c:134 +#: ../tgp-msg.c:132 #, c-format msgid "%2$s made a screenshot of %1$d messages." msgstr "%2$s bëri një foto ekrani të %1$d mesazheve." -#: ../tgp-msg.c:137 -#, c-format -msgid "%2$s updated to layer %1$d." -msgstr "%2$s e përditësoi me shtresën %1$d." - -#: ../tgp-msg.c:140 -#, c-format -msgid "%2$s requests rekey #%1$016llx." -msgstr "%2$s kërkon kyçkëmbim #%1$016llx." - -#: ../tgp-msg.c:143 -#, c-format -msgid "%2$s accepts rekey #%1$016llx." -msgstr "%2$s pranon kyçkëmbim #%1$016llx." - -#: ../tgp-msg.c:146 -#, c-format -msgid "%2$s commits rekey #%1$016llx." -msgstr "%2$s parashtron kyçkëmbim #%1$016llx." - -#: ../tgp-msg.c:149 -#, c-format -msgid "%2$s aborts rekey #%1$016llx." -msgstr "%2$s dështon kyçkëmbim #%1$016llx." - -#: ../tgp-msg.c:173 +#: ../tgp-msg.c:156 #, c-format msgid "Sending message failed. %d: %s" msgstr "Dërgimi i mesazhit dështoi. %d: %s" -#: ../tgp-msg.c:251 +#: ../tgp-msg.c:259 msgid "Sending image failed." msgstr "Dërgimi i figurës dështoi." -#: ../tgp-msg.c:265 +#: ../tgp-msg.c:273 msgid "Sorry, sending documents to encrypted chats not yet supported." msgstr "Na ndjeni, dërgimi i dokumenteve në fjalosje të fshehtëzuara nuk mbulohet ende." -#: ../tgp-msg.c:352 +#: ../tgp-msg.c:360 #, c-format msgid "%s sent a sticker." msgstr "%s dërgoi një ngjitëse." @@ -460,49 +435,49 @@ msgstr "Doni të krijoni një fjalosje të re grupi me emrin '%s'?" #. This should be the language's timestamp format. #. * This is preceded by a colon. -#: ../tgp-utils.c:39 +#: ../tgp-utils.c:33 msgid "%d.%m.%Y %H:%M" msgstr "%d.%m.%Y %H:%M" #. This is preceded by a colon. -#: ../tgp-utils.c:60 +#: ../tgp-utils.c:54 #, c-format msgid "recently" msgstr "së fundi" #. This is preceded by a colon. -#: ../tgp-utils.c:64 +#: ../tgp-utils.c:58 #, c-format msgid "last week" msgstr "javën e fundit" #. This is preceded by a colon. -#: ../tgp-utils.c:68 +#: ../tgp-utils.c:62 #, c-format msgid "last month" msgstr "muajin e fundit" #. This is preceded by a colon. It refers to a point on time. -#: ../tgp-utils.c:72 +#: ../tgp-utils.c:66 msgid "unknown" msgstr "e panjohur" -#: ../tgp-chat.c:83 +#: ../tgp-chat.c:79 msgid "You have already left this chat." msgstr "E keni lëndë tashmë këtë fjalosje." -#: ../tgp-chat.c:133 +#: ../tgp-chat.c:122 msgid "Subject:" msgstr "Subjekt:" -#: ../tgp-chat.c:139 +#: ../tgp-chat.c:128 msgid "Invite link:" msgstr "Lidhje ftese:" -#: ../tgp-chat.c:145 +#: ../tgp-chat.c:134 msgid "Chat ID:" msgstr "ID Fjalosjeje:" -#: ../tgp-chat.c:244 +#: ../tgp-chat.c:232 msgid "Users" msgstr "Përdorues" diff --git a/po/telegram-purple.pot b/po/telegram-purple.pot index 5d729a4..ee5987a 100644 --- a/po/telegram-purple.pot +++ b/po/telegram-purple.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-10-12 18:48+0200\n" +"POT-Creation-Date: 2015-10-19 15:06+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -49,281 +49,256 @@ msgstr "" msgid "Query Failed" msgstr "" -#: ../telegram-purple.c:172 +#: ../telegram-purple.c:202 msgid "Secret chat terminated." msgstr "" -#: ../telegram-purple.c:215 +#: ../telegram-purple.c:247 msgid "Message marked as read." msgstr "" -#: ../telegram-purple.c:475 +#: ../telegram-purple.c:484 #, c-format msgid "Invite link: %s" msgstr "" -#: ../telegram-purple.c:498 ../telegram-purple.c:499 +#: ../telegram-purple.c:504 ../telegram-purple.c:505 msgid "Creating chat link failed" msgstr "" -#: ../telegram-purple.c:500 +#: ../telegram-purple.c:506 msgid "You need to be admin of the group to do that." msgstr "" -#: ../telegram-purple.c:526 +#: ../telegram-purple.c:528 msgid "Chat joined" msgstr "" -#: ../telegram-purple.c:527 +#: ../telegram-purple.c:529 msgid "Chat added to list of chat rooms." msgstr "" -#: ../telegram-purple.c:541 +#: ../telegram-purple.c:543 msgid "Start secret chat ..." msgstr "" #. Generate Public Link -#: ../telegram-purple.c:547 +#: ../telegram-purple.c:549 msgid "Invite users by link ..." msgstr "" #. Delete self from chat -#: ../telegram-purple.c:553 +#: ../telegram-purple.c:555 msgid "Delete and exit ..." msgstr "" -#: ../telegram-purple.c:571 +#: ../telegram-purple.c:573 #, c-format msgid "" "Error, server public key not found at %s. Make sure that telegram-purple is " "installed properly." msgstr "" -#: ../telegram-purple.c:580 +#: ../telegram-purple.c:582 #, c-format msgid "Unable to sign on as %s: missing file %s." msgstr "" -#: ../telegram-purple.c:584 +#: ../telegram-purple.c:586 msgid "" "Make sure telegram-purple is installed properly,\n" "including the .tglpub file." msgstr "" -#: ../telegram-purple.c:602 +#: ../telegram-purple.c:604 #, c-format msgid "Unable to sign on as %s: phone number lacks country prefix." msgstr "" -#: ../telegram-purple.c:606 +#: ../telegram-purple.c:608 msgid "" "Numbers must start with the full international\n" "prefix code, e.g. +49 for Germany." msgstr "" -#: ../telegram-purple.c:750 ../telegram-purple.c:751 +#: ../telegram-purple.c:733 ../telegram-purple.c:734 msgid "Cannot invite buddy to chat" msgstr "" -#: ../telegram-purple.c:752 +#: ../telegram-purple.c:735 msgid "Specified user does not exist." msgstr "" #. Login -#: ../telegram-purple.c:895 +#: ../telegram-purple.c:877 msgid "Password (two factor authentication)" msgstr "" -#: ../telegram-purple.c:901 +#: ../telegram-purple.c:883 msgid "" "Fallback SMS verification\n" "(Helps when not using Pidgin and you aren't being prompted for the code)" msgstr "" -#: ../telegram-purple.c:909 +#: ../telegram-purple.c:891 msgid "ask" msgstr "" -#: ../telegram-purple.c:910 +#: ../telegram-purple.c:892 msgid "always" msgstr "" -#: ../telegram-purple.c:911 +#: ../telegram-purple.c:893 msgid "never" msgstr "" -#: ../telegram-purple.c:913 +#: ../telegram-purple.c:895 msgid "Accept secret chats" msgstr "" -#: ../telegram-purple.c:918 +#: ../telegram-purple.c:900 msgid "Display buddies offline after (days)" msgstr "" -#: ../telegram-purple.c:923 +#: ../telegram-purple.c:905 msgid "Fetch past history on first login" msgstr "" -#: ../telegram-purple.c:928 +#: ../telegram-purple.c:910 msgid "" "Don't fetch history older than (days)\n" "(0 for unlimited)" msgstr "" #. Chats -#: ../telegram-purple.c:936 +#: ../telegram-purple.c:918 msgid "Add all group chats to buddy list" msgstr "" #. Read notifications -#: ../telegram-purple.c:944 +#: ../telegram-purple.c:926 msgid "Display notices of receipt" msgstr "" -#: ../telegram-purple.c:949 +#: ../telegram-purple.c:931 msgid "Send notices of receipt when present" msgstr "" -#: ../tgp-2prpl.c:386 ../tgp-request.c:130 +#: ../tgp-2prpl.c:167 ../tgp-request.c:130 msgid "First name" msgstr "" -#: ../tgp-2prpl.c:387 ../tgp-request.c:132 +#: ../tgp-2prpl.c:168 ../tgp-request.c:132 msgid "Last name" msgstr "" -#: ../tgp-2prpl.c:389 +#: ../tgp-2prpl.c:170 msgid "Name" msgstr "" -#: ../tgp-2prpl.c:394 ../tgp-request.c:246 ../tgp-request.c:250 +#: ../tgp-2prpl.c:175 ../tgp-request.c:246 ../tgp-request.c:250 #: ../tgp-request.c:254 msgid "Username" msgstr "" -#: ../tgp-2prpl.c:399 +#: ../tgp-2prpl.c:180 msgid "Last seen" msgstr "" -#: ../tgp-2prpl.c:404 +#: ../tgp-2prpl.c:185 msgid "Phone" msgstr "" -#: ../tgp-2prpl.c:417 +#: ../tgp-2prpl.c:197 msgid "Waiting for the user to get online ..." msgstr "" -#: ../tgp-2prpl.c:421 +#: ../tgp-2prpl.c:201 msgid "Self destruction timer" msgstr "" -#: ../tgp-2prpl.c:427 +#: ../tgp-2prpl.c:207 msgid "Off" msgstr "" -#: ../tgp-2prpl.c:434 +#: ../tgp-2prpl.c:214 msgid "Secret key" msgstr "" -#: ../tgp-msg.c:55 +#: ../tgp-msg.c:53 #, c-format msgid "%2$s created chat %1$s." msgstr "" -#: ../tgp-msg.c:58 +#: ../tgp-msg.c:56 #, c-format msgid "%2$s changed title to %1$s." msgstr "" -#: ../tgp-msg.c:61 +#: ../tgp-msg.c:59 #, c-format msgid "%s changed photo." msgstr "" -#: ../tgp-msg.c:64 +#: ../tgp-msg.c:62 #, c-format msgid "%s deleted photo." msgstr "" -#: ../tgp-msg.c:72 +#: ../tgp-msg.c:70 #, c-format msgid "%1$s added user %2$s by link." msgstr "" -#: ../tgp-msg.c:85 +#: ../tgp-msg.c:83 #, c-format msgid "%2$s added user %1$s." msgstr "" -#: ../tgp-msg.c:107 +#: ../tgp-msg.c:104 #, c-format msgid "%1$s deleted user %2$s." msgstr "" -#: ../tgp-msg.c:120 +#: ../tgp-msg.c:118 #, c-format msgid "%2$s deleted user %1$s." msgstr "" -#: ../tgp-msg.c:125 +#: ../tgp-msg.c:123 #, c-format msgid "%2$s set self destruction timer to %1$d seconds." msgstr "" -#: ../tgp-msg.c:128 +#: ../tgp-msg.c:126 #, c-format msgid "%2$s marked %1$d messages read." msgstr "" -#: ../tgp-msg.c:131 +#: ../tgp-msg.c:129 #, c-format msgid "%2$s deleted %1$d messages." msgstr "" -#: ../tgp-msg.c:134 +#: ../tgp-msg.c:132 #, c-format msgid "%2$s made a screenshot of %1$d messages." msgstr "" -#: ../tgp-msg.c:137 -#, c-format -msgid "%2$s updated to layer %1$d." -msgstr "" - -#: ../tgp-msg.c:140 -#, c-format -msgid "%2$s requests rekey #%1$016llx." -msgstr "" - -#: ../tgp-msg.c:143 -#, c-format -msgid "%2$s accepts rekey #%1$016llx." -msgstr "" - -#: ../tgp-msg.c:146 -#, c-format -msgid "%2$s commits rekey #%1$016llx." -msgstr "" - -#: ../tgp-msg.c:149 -#, c-format -msgid "%2$s aborts rekey #%1$016llx." -msgstr "" - -#: ../tgp-msg.c:173 +#: ../tgp-msg.c:156 #, c-format msgid "Sending message failed. %d: %s" msgstr "" -#: ../tgp-msg.c:251 +#: ../tgp-msg.c:259 msgid "Sending image failed." msgstr "" -#: ../tgp-msg.c:265 +#: ../tgp-msg.c:273 msgid "Sorry, sending documents to encrypted chats not yet supported." msgstr "" -#: ../tgp-msg.c:352 +#: ../tgp-msg.c:360 #, c-format msgid "%s sent a sticker." msgstr "" @@ -459,49 +434,49 @@ msgstr "" #. This should be the language's timestamp format. #. * This is preceded by a colon. -#: ../tgp-utils.c:39 +#: ../tgp-utils.c:33 msgid "%d.%m.%Y %H:%M" msgstr "" #. This is preceded by a colon. -#: ../tgp-utils.c:60 +#: ../tgp-utils.c:54 #, c-format msgid "recently" msgstr "" #. This is preceded by a colon. -#: ../tgp-utils.c:64 +#: ../tgp-utils.c:58 #, c-format msgid "last week" msgstr "" #. This is preceded by a colon. -#: ../tgp-utils.c:68 +#: ../tgp-utils.c:62 #, c-format msgid "last month" msgstr "" #. This is preceded by a colon. It refers to a point on time. -#: ../tgp-utils.c:72 +#: ../tgp-utils.c:66 msgid "unknown" msgstr "" -#: ../tgp-chat.c:83 +#: ../tgp-chat.c:79 msgid "You have already left this chat." msgstr "" -#: ../tgp-chat.c:133 +#: ../tgp-chat.c:122 msgid "Subject:" msgstr "" -#: ../tgp-chat.c:139 +#: ../tgp-chat.c:128 msgid "Invite link:" msgstr "" -#: ../tgp-chat.c:145 +#: ../tgp-chat.c:134 msgid "Chat ID:" msgstr "" -#: ../tgp-chat.c:244 +#: ../tgp-chat.c:232 msgid "Users" msgstr "" diff --git a/telegram-base.c b/telegram-base.c index 9e231ea..50a721f 100644 --- a/telegram-base.c +++ b/telegram-base.c @@ -437,7 +437,7 @@ void read_secret_chat_file (struct tgl_state *TLS) { close (secret_chat_fd); } -gchar *get_config_dir (struct tgl_state *TLS, char const *username) { +gchar *get_config_dir (char const *username) { gchar *dir = g_strconcat (purple_user_dir(), G_DIR_SEPARATOR_S, config_dir, G_DIR_SEPARATOR_S, username, NULL); @@ -452,6 +452,18 @@ gchar *get_config_dir (struct tgl_state *TLS, char const *username) { return dir; } +gchar *get_user_pk_path () { + /* This can't be conditional on whether or not we're using telepathy, because + * then we would need to make sure that `make local_install` also knows about + * that location. So we *always* use ${HOME}/.purple/telegram-purple, + * even when the other files aren't in this folder. + * Note that this is only visible when using Telepathy/Empathy with + * local_install, which should be kinda rare anyway (use telepathy-morse!). */ + return g_strconcat (g_get_home_dir(), G_DIR_SEPARATOR_S, ".purple", + G_DIR_SEPARATOR_S, "telegram-purple", + G_DIR_SEPARATOR_S, user_pk_filename, NULL); +} + gchar *get_download_dir (struct tgl_state *TLS) { assert (TLS->base_path); static gchar *dir; diff --git a/telegram-base.h b/telegram-base.h index ddf3740..d061b52 100644 --- a/telegram-base.h +++ b/telegram-base.h @@ -42,7 +42,8 @@ void write_secret_chat_gw (struct tgl_state *TLS, void *extra, int success, stru void telegram_login (struct tgl_state *TLS); void telegram_export_authorization (struct tgl_state *TLS); -gchar *get_config_dir (struct tgl_state *TLS, char const *username); +gchar *get_config_dir (char const *username); +gchar *get_user_pk_path (); gchar *get_download_dir (struct tgl_state *TLS); gboolean assert_file_exists (PurpleConnection *gc, const char *filepath, const char *format); diff --git a/telegram-purple.c b/telegram-purple.c index 20b946c..6539f58 100644 --- a/telegram-purple.c +++ b/telegram-purple.c @@ -76,9 +76,10 @@ static void update_secret_chat_handler (struct tgl_state *TLS, struct tgl_secret static void update_user_typing (struct tgl_state *TLS, struct tgl_user *U, enum tgl_typing_status status); static void update_marked_read (struct tgl_state *TLS, int num, struct tgl_message *list[]); static char *format_print_name (struct tgl_state *TLS, tgl_peer_id_t id, const char *a1, const char *a2, const char *a3, const char *a4); -void on_user_get_info (struct tgl_state *TLS, void *info_data, int success, struct tgl_user *U); +static void on_user_get_info (struct tgl_state *TLS, void *info_data, int success, struct tgl_user *U); const char *config_dir = "telegram-purple"; +const char *user_pk_filename = "server.tglpub"; const char *pk_path = "/etc/telegram-purple/server.tglpub"; struct tgl_update_callback tgp_callback = { @@ -568,30 +569,45 @@ static void tgprpl_login (PurpleAccount * acct) { connection_data *conn = connection_data_init (TLS, gc, acct); purple_connection_set_protocol_data (gc, conn); - TLS->base_path = get_config_dir (TLS, purple_account_get_username (acct)); + TLS->base_path = get_config_dir (purple_account_get_username (acct)); tgl_set_download_directory (TLS, get_download_dir(TLS)); - if (!assert_file_exists (gc, pk_path, _("Error, server public key not found at %s." - " Make sure that telegram-purple is installed properly."))) { - /* Already reported. */ - return; - } debug ("base configuration path: '%s'", TLS->base_path); - struct rsa_pubkey the_pubkey; - if (! read_pubkey_file (pk_path, &the_pubkey)) { - char *cause = g_strdup_printf (_("Unable to sign on as %s: missing file %s."), - purple_account_get_username (acct), pk_path); - purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, cause); - purple_notify_message (_telegram_protocol, PURPLE_NOTIFY_MSG_ERROR, cause, - _("Make sure telegram-purple is installed properly,\n" - "including the .tglpub file."), NULL, NULL, NULL); - g_free (cause); - return; - } + struct rsa_pubkey pubkey; + debug ("trying global pubkey at %s", pk_path); + gboolean global_pk_loaded = read_pubkey_file (pk_path, &pubkey); tgl_set_verbosity (TLS, 4); - tgl_set_rsa_key_direct (TLS, the_pubkey.e, the_pubkey.n_len, the_pubkey.n_raw); - + if (global_pk_loaded) { + debug ("using global pubkey"); + tgl_set_rsa_key_direct (TLS, pubkey.e, pubkey.n_len, pubkey.n_raw); + } else { + char *user_pk_path = get_user_pk_path (); + debug ("trying local pubkey at %s", user_pk_path); + gboolean user_pk_loaded = read_pubkey_file (user_pk_path, &pubkey); + + if (user_pk_loaded) { + debug ("using local pubkey"); + tgl_set_rsa_key_direct (TLS, pubkey.e, pubkey.n_len, pubkey.n_raw); + } else { + debug ("both didn't work. abort."); + char *cause = g_strdup_printf (_("Unable to sign on as %s: pubkey not found."), + purple_account_get_username (acct)); + purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, cause); + char *long_hint = g_strdup_printf ( + _("Make sure telegram-purple is installed properly,\n" + "including the .tglpub file.\n" + "If you're running SELinux (e.g. when using Tails),\n" + "try 'make local_install', or simply copy\n" + "%1$s to %2$s."), pk_path, user_pk_path); + purple_notify_message (_telegram_protocol, PURPLE_NOTIFY_MSG_ERROR, cause, + long_hint, NULL, NULL, NULL); + g_free (cause); + g_free (long_hint); + return; + } + } + tgl_set_ev_base (TLS, conn); tgl_set_net_methods (TLS, &tgp_conn_methods); tgl_set_timer_methods (TLS, &tgp_timers); diff --git a/telegram-purple.h b/telegram-purple.h index 067336d..72de85e 100644 --- a/telegram-purple.h +++ b/telegram-purple.h @@ -81,6 +81,7 @@ void on_ready (struct tgl_state *TLS); extern const char *pk_path; +extern const char *user_pk_filename; extern const char *config_dir; extern PurplePlugin *_telegram_protocol; void export_chat_link_checked (struct tgl_state *TLS, const char *name); diff --git a/tgl b/tgl index 1789d77..5b725d2 160000 --- a/tgl +++ b/tgl @@ -1 +1 @@ -Subproject commit 1789d7780d5a65ef53348845cd51db595d39835a +Subproject commit 5b725d288f59ada3f8905a73182fe57ae8c22986 diff --git a/tgp-2prpl.c b/tgp-2prpl.c index cb29fb2..6797617 100644 --- a/tgp-2prpl.c +++ b/tgp-2prpl.c @@ -31,6 +31,7 @@ #include "tgp-utils.h" #include "telegram-base.h" #include "tgp-msg.h" +#include "tgp-net.h" #include #include @@ -68,6 +69,11 @@ connection_data *pbn_get_conn (PurpleBlistNode *node) { return NULL; } +connection_data *c_get_conn (struct connection *c) { + struct tgl_state *TLS = c->TLS; + return TLS->ev_base; +} + int p2tgl_status_is_present (PurpleStatus *status) { const char *name = purple_status_get_id (status); return !(strcmp (name, "unavailable") == 0 || strcmp (name, "away") == 0); @@ -248,6 +254,10 @@ int p2tgl_imgstore_add_with_id (const char* filename) { } #ifdef HAVE_LIBWEBP + +static const int MAX_W = 256; +static const int MAX_H = 256; + int p2tgl_imgstore_add_with_id_webp (const char *filename) { const uint8_t *data = NULL; @@ -264,15 +274,28 @@ int p2tgl_imgstore_add_with_id_webp (const char *filename) { g_free ((gchar *)data); return 0; } - int H = config.input.height; - int W = config.input.width; - while (H > 256 || W > 256) { - H /= 2; - W /= 2; + + config.options.use_scaling = 0; + config.options.scaled_width = config.input.width; + config.options.scaled_height = config.input.height; + if (config.options.scaled_width > MAX_W || config.options.scaled_height > MAX_H) { + const float max_scale_width = MAX_W * 1.0f / config.options.scaled_width; + const float max_scale_height = MAX_H * 1.0f / config.options.scaled_height; + if (max_scale_width < max_scale_height) { + /* => the width is most limiting */ + config.options.scaled_width = MAX_W; + /* Can't use ' *= ', because we need to do the multiplication in float + * (or double), and only THEN cast back to int. */ + config.options.scaled_height = (int) (config.options.scaled_height * max_scale_width); + } else { + /* => the height is most limiting */ + config.options.scaled_height = MAX_H; + /* Can't use ' *= ', because we need to do the multiplication in float + * (or double), and only THEN cast back to int. */ + config.options.scaled_width = (int) (config.options.scaled_width * max_scale_height); + } + config.options.use_scaling = 1; } - config.options.use_scaling = 1; - config.options.scaled_width = W; - config.options.scaled_height = H; config.output.colorspace = MODE_RGBA; if (! WebPDecode(data, len, &config) == VP8_STATUS_OK) { warning ("error decoding webp: %s", filename); @@ -291,11 +314,11 @@ int p2tgl_imgstore_add_with_id_webp (const char *filename) { warning ("error encoding webp as png: %s", filename); return 0; } - + // will be owned by libpurple imgstore, which uses glib functions for managing memory void *pngdub = g_memdup (png, (guint)pnglen); free (png); - + int imgStoreId = purple_imgstore_add_with_id (pngdub, pnglen, NULL); return imgStoreId; } diff --git a/tgp-2prpl.h b/tgp-2prpl.h index a321d9a..3378201 100644 --- a/tgp-2prpl.h +++ b/tgp-2prpl.h @@ -34,6 +34,7 @@ connection_data *tg_get_data (struct tgl_state *TLS); connection_data *gc_get_conn (PurpleConnection *gc); connection_data *pa_get_conn (PurpleAccount *pa); connection_data *pbn_get_conn (PurpleBlistNode *node); +connection_data *c_get_conn (struct connection *c); tgl_peer_t *p2tgl_get_peer (tgl_peer_id_t peer); tgl_peer_t *p2tgl_get_peer_by_id (int id); @@ -59,6 +60,10 @@ PurpleNotifyUserInfo *p2tgl_notify_user_info_new (struct tgl_user *U); PurpleNotifyUserInfo *p2tgl_notify_encrypted_chat_info_new (struct tgl_state *TLS, struct tgl_secret_chat *secret, struct tgl_user *U); int p2tgl_imgstore_add_with_id (const char* filename); -int p2tgl_imgstore_add_with_id_webp (const char *filename); void p2tgl_buddy_icons_set_for_user (PurpleAccount *pa, tgl_peer_id_t id, const char* filename); + +#ifdef HAVE_LIBWEBP +int p2tgl_imgstore_add_with_id_webp (const char *filename); +#endif + #endif diff --git a/tgp-msg.c b/tgp-msg.c index 7caf6bb..450827a 100644 --- a/tgp-msg.c +++ b/tgp-msg.c @@ -356,7 +356,7 @@ static char *tgp_msg_sticker_display (struct tgl_state *TLS, tgl_peer_id_t from, text = tgp_format_img (img); *flags |= PURPLE_MESSAGE_IMAGES; #else - char *txt_user = tgp_blist_peer_get_purple_name (TLS, from) + const char *txt_user = tgp_blist_peer_get_purple_name (TLS, from); text = g_strdup_printf (_("%s sent a sticker."), txt_user); *flags |= PURPLE_MESSAGE_SYSTEM; #endif diff --git a/tgp-net.c b/tgp-net.c index 88fdfa1..416790d 100644 --- a/tgp-net.c +++ b/tgp-net.c @@ -38,6 +38,7 @@ #include "tgp-net.h" #include "tgp-structs.h" +#include "tgp-2prpl.h" #include "telegram-base.h" #include #include @@ -273,6 +274,17 @@ static void net_on_connected (gpointer arg, gint fd, const gchar *error_message) start_ping_timer (c); } +static void net_on_connected_assert_success (gpointer arg, gint fd, const gchar *error_message) { + struct connection *c = arg; + struct tgl_state *TLS = c->TLS; + if (fd == -1) { + info ("Connection to main data center (%d) %s:%d not possible\n", c->dc->id, c->ip, c->port); + purple_connection_error_reason (tg_get_conn (TLS), PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Cannot connect to server")); + return; + } + net_on_connected (arg, fd, error_message); +} + struct connection *tgln_create_connection (struct tgl_state *TLS, const char *host, int port, struct tgl_session *session, struct tgl_dc *dc, struct mtproto_methods *methods) { struct connection *c = malloc (sizeof (*c)); memset (c, 0, sizeof (*c)); @@ -296,8 +308,8 @@ struct connection *tgln_create_connection (struct tgl_state *TLS, const char *ho c->session = session; c->methods = methods; - connection_data *conn = TLS->ev_base; - c->prpl_data = purple_proxy_connect (conn->gc, conn->pa, host, port, net_on_connected, c); + c->prpl_data = purple_proxy_connect (tg_get_conn(TLS), tg_get_acc(TLS), host, port, + TLS->dc_working_num == dc->id ? net_on_connected_assert_success : net_on_connected, c); start_fail_timer (c); diff --git a/tgp-utils.c b/tgp-utils.c index ea78a8d..2262b76 100644 --- a/tgp-utils.c +++ b/tgp-utils.c @@ -22,7 +22,6 @@ #include "tgp-utils.h" #include "msglog.h" -#include "lodepng/lodepng.h" #include @@ -127,4 +126,3 @@ int tgp_startswith (const char *str, const char *with) { } return TRUE; } -