Giter Site home page Giter Site logo

id3v2lib's People

Contributors

briansorahan avatar choi-inkyun avatar comicsansms avatar gray-wind avatar hopeseekr avatar kdeng00 avatar koffeinflummi avatar kontinuation avatar larsbs avatar moritzschaefer avatar pascal-cuoq avatar sizeak avatar timtam avatar zeuno8 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

id3v2lib's Issues

Segmentation faults 2017-06-25

Hello, I was using libFuzzer and American Fuzzy Lop (afl-fuzz) to fuzz input to a test program using id3v2lib on Linux. Is fixing the crashes from these input files something you're interested in? The input files and example test.c program can be found here: https://github.com/rwhitworth/id3v2lib-fuzz/tree/master/2017-06-25

The files can be executed as ./test id_filename to cause seg faults.

Let me know if I can provide any more information to help narrow down this issue. I had difficulty compiling the library with debugging enabled so the gdb backtraces may not be as useful as they could be.

id:000001,sig:11,src:000019,op:havoc,rep:2

#0  __memmove_sse2_unaligned_erms () at ../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S:363
363     ../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
(gdb) bt
#0  __memmove_sse2_unaligned_erms () at ../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S:363
#1  0x000000000040192e in load_tag_with_buffer ()
#2  0x00000000004015af in load_tag ()
#3  0x000000000040122b in main (argc=2, argv=0x7ffe610b9218) at test.c:10

id:000002,sig:11,src:000022,op:int32,pos:6,val:be:+1

#0  __memmove_sse2_unaligned_erms () at ../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S:420
420     ../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
(gdb) bt
#0  __memmove_sse2_unaligned_erms () at ../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S:420
#1  0x0000000000406621 in parse_frame ()
#2  0x00000000004019cf in load_tag_with_buffer ()
#3  0x00000000004015af in load_tag ()
#4  0x000000000040122b in main (argc=2, argv=0x7ffcdc7b0c58) at test.c:10

Question regarding this library

Hi Lars,

Thanks for this amazing and light library. However, I am currently running into problems with parsing some mp3 files. For these files the library spits out garbage strings, any thoughts as to what could be causing this?

Thank you,
Jim

Add new binary frame

Hi,

First: thanks for this nice library!

I would like to write a non-standard frame type (ETCO).
This is a binary frame type, so I suppose I cannot use ID3v2_Tag_set_text_frame.

I'm able to create the frame ID3v2_Frame struct manually, but I'm not able to add the frame to the frame list of the tag, because FrameList_add_frame() is private.
Is there any way I can add a frame, that is not text, comment or apic frame, but a binary frame, to the list of frames of a tag?
Or, would it be possible to make FrameList_add_frame non-private?

Thanks!

Requires extern "C"

When using this with C++, it breaks on all functions and can only be resolved by placing an extern "C" block around the

#include <id3v2lib.h>

statement. Please resolve this in the include files you provide.

i dont know, how i build the dll

Hallo,

i dont know what i should do. I dont understand the instructions in the read me. Do you have an Video tutorial?

Building using Microsoft Visual Studio
Microsoft Visual Studio needs a slightly different way of building. Open the Visual Studio Developers Console, ch into the id3v2lib folder and execute the following:

$ mkdir build && cd build
$ cmake ..

This should leave you with several MSVS projects in the \build directory. Open ALL_BUILD.vcxproj with Visual Studio and build it as usual. The resulting lib file can be found in \build\src\Debug\id3v2.lib

Error cannot find -lid3v2lib: No such file or directory

Dear lars,

sorry if this question already asked.

When I try to compile I got this error
~$ gcc -o example example.c -lid3v2lib
cannot find -lid3v2lib: No such file or directory

file example.c and libid3v2.a on same location.
Any idea how to solve ?

tag_set_comment always sets the comment to "eng"

For some reason whenever the comment tag is set it is set to "eng".

The following demonstrates the issue. I've tested several different mp3 files.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>

#include "id3v2lib.h"

void print_all_tags(const char *file)
{
    ID3v2_tag* tag = load_tag(file); // Load the full tag from the file
    if (tag == NULL) {
        printf("%s: no tag found\n", file);
    }
    else {
        ID3v2_frame* f = tag_get_title(tag);
        ID3v2_frame_text_content* tc = parse_text_frame_content(f);
        if (tc != NULL) {
            printf("TITLE: %s\n", tc->data);
        } else {
            printf("failed to parse TITLE\n");
        }

        f = tag_get_artist(tag);
        tc = parse_text_frame_content(f);
        if (tc != NULL) {
            printf("ARTIST: %s\n", tc->data);
        } else {
            printf("failed to parse ARTIST\n");
        }

        f = tag_get_album(tag);
        tc = parse_text_frame_content(f);
        if (tc != NULL) {
            printf("ALBUM: %s\n", tc->data);
        } else {
            printf("failed to parse ALBUM\n");
        }

        f = tag_get_album_artist(tag);
        tc = parse_text_frame_content(f);
        if (tc != NULL) {
            printf("ALBUM ARTIST: %s\n", tc->data);
        } else {
            printf("failed to parse ALBUM ARTIST\n");
        }

        f = tag_get_genre(tag);
        tc = parse_text_frame_content(f);
        if (tc != NULL) {
            printf("GENRE: %s\n", tc->data);
        } else {
            printf("failed to parse GENRE\n");
        }

        f = tag_get_track(tag);
        tc = parse_text_frame_content(f);
        if (tc != NULL) {
            printf("TRACK: %s\n", tc->data);
        } else {
            printf("failed to parse TRACK\n");
        }

        f = tag_get_year(tag);
        tc = parse_text_frame_content(f);
        if (tc != NULL) {
            printf("YEAR: %s\n", tc->data);
        } else {
            printf("failed to parse YEAR\n");
        }

        f = tag_get_comment(tag);
        tc = parse_text_frame_content(f);
        if (tc != NULL) {
            printf("COMMENT: %s\n", tc->data);
        } else {
            printf("failed to parse COMMENT\n");
        }

        f = tag_get_disc_number(tag);
        tc = parse_text_frame_content(f);
        if (tc != NULL) {
            printf("DISC NUMBER: %s\n", tc->data);
        } else {
            printf("failed to parse DISC NUMBER\n");
        }

        f = tag_get_composer(tag);
        tc = parse_text_frame_content(f);
        if (tc != NULL) {
            printf("COMPOSER: %s\n", tc->data);
        } else {
            printf("failed to parse COMPOSER\n");
        }
    }
}

int main(int argc, char *argv[])
{
    char *file = argv[1];

    // print initial state
    print_all_tags(file);

    ID3v2_tag* tag = load_tag(file);
    if(tag == NULL)
    {
        tag = new_tag();
    }
    tag_set_title("Some great song", 0, tag);
    set_tag(file, tag);

    // print all tags after setting title
    print_all_tags(file);

    tag = load_tag(file);
    if(tag == NULL)
    {
        tag = new_tag();
    }
    tag_set_comment("comment 123", 0, tag);
    set_tag(file, tag);

    // print all tags after setting comment
    print_all_tags(file);

    return EXIT_SUCCESS;
}

It prints the following

$ ./tagmp3 tiny.mp3 
tiny.mp3: no tag found
TITLE: Some great song
failed to parse ARTIST
failed to parse ALBUM
failed to parse ALBUM ARTIST
failed to parse GENRE
failed to parse TRACK
failed to parse YEAR
failed to parse COMMENT
failed to parse DISC NUMBER
failed to parse COMPOSER
TITLE: Some great song
failed to parse ARTIST
failed to parse ALBUM
failed to parse ALBUM ARTIST
failed to parse GENRE
failed to parse TRACK
failed to parse YEAR
COMMENT: eng
failed to parse DISC NUMBER
failed to parse COMPOSER

Why is comment set to "eng" ?

parse_frame exceeds memory allocated by load_tag

I have encountered many cases where parse_frame tries to copy more data from the raw tag data than the size of the memory that has been allocated for it. I assume the problem is with the size of the memory to be read set by btoi, but a simple check that the frame's target size in parse_frame doesn't exceed the size mallocated in load_tag solves the problem for now. I believe my poorly tagged songs are part of the issue, but segmentation faults are undesirable.
If you need output, I would be happy to provide it.

Variable Length Arrays not supported by MSVC.

Hi, I'm not sure if it's something you want to support, but you can't currently build this with MSVC (Visual Studio). "I don't plan to support MSVC." is a perfectly reasonable response IMO, so no pressure! I don't usually build for Windows, but the Conan CI builds for it by default, so I've been testing with VS 2019.

It seems that they don't support VLAs since they were made optional in C11, and have no plans to ever support them:
https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/#variable-length-arrays

I suppose to support MSVC the VLAs would need replacing with good old malloc. WDYT?

EXC_BAD_ACCESS Error

hi,
Thanks a lot for id3v2lib which helps me insert ID3v2 Tag to mp3 files with no metadata before.
But sometimes I got this error "malloc: *** error for object 0x172834d40: Invalid pointer dequeued from free list" and I can't find out what's wrong. Is there any advice ?

need to write tag to a buffer, not to file

Hi, I need to write the tag to a buffer, not to a file. I need this so that I can add "id3 " blocks to a wave file. Apparently, software like Audacity does that, and I need a CLI program that can also do so. Thanks.

Need information about ID3 parser for MPEG2-TS file

Hi,

I found your software for ID3 extraction. This is working very good and I am able to understand some thing for that. It is a amazing work.

https://github.com/larsbs/id3v2lib
I have one question for you, did you try to support ID3 parsing for MPEG2-TS streams (from HLS)? I am looking for that code base which parses the ID3 tags from the MPEG2-TS streams (from HLS).
Could you please guide me ?
Warm Regards,

Sunil Deshpande
Bangalore

Crash when using frame->size without checking

The line of code:
frame->size = btoi(bytes, 4, offset += ID3_FRAME_ID);

Takes the value found inside the frame without looking whether or not the data that is expected is found, this can be used to cause a read overrun as:
memcpy(frame->data, bytes + (offset += ID3_FRAME_FLAGS), frame->size);

Reads beyond the data

In addition, since size is an int a value that is negative can be returned, causing the allocation '0' in the malloc:
frame->data = (char*) malloc(frame->size * sizeof(char));

And a memcpy into a NULL pointer

mangled tags

When the altered file is read with id3v2 -l,
title has "ng " prepended.
album has first two characters missing.
album artist has first character missing.
disk number is blank

A hexdump shows that the full strings are present, so it must be a problem writing the frame lengths.

Buffer read support

It would be helpful to add buffer read support besides file reading. I am implementing a file streamer/player at the moment and want to read id3 data directly from the stream.
There is no library available (i know of) that reads id3 labels from a buffer rather than from a file.

It just doesn't read tags :-(

Tell me why the following doesn't work!

#include <iostream>
#include <id3v2lib.h>

using std::cout;
using std::endl;

int main(int argc, char* argv[])
{
    ID3v2_header* header = get_tag_header(argv[1]);
    if (header != NULL) {
        cout << "Header is NOT NULL! Woohoo!!\n";
        if (has_id3v2tag(header)) {
            cout << "OMFG! The file has an ID3v2 tag!!" << endl;
        }
        else {
            cout << "Oh man! The file DOES NOT have an ID3v2 tag. :-(" << endl;
        }
    }
    else {
        cout << "Header is NULL!!\n";
    }

    ID3v2_tag* tag = load_tag(argv[1]);
    if (tag != NULL) {
        ID3v2_frame* title_frame = tag_get_title(tag);
        ID3v2_frame_text_content* content;

        content = parse_text_frame_content(title_frame);
        printf("Title: %s\n", content->data);
    }
    else {
        cout << "Tag is NULL!!\n";
    }

    return 0;
}

Output:

Header is NOT NULL! Woohoo!!
OMFG! The file has an ID3v2 tag!!
Tag is NULL!!

Adding genre feature

Hey @larsbs,
I was wondering if I added a feature to parse the genre number to an actual string would you accept the pull request? I wouldn't change the function get_genre_content() but add a function in utils given an ID3v2_frame_text_content data member to a string if the data value is an actual genre number supported by the ID3 genre list.

free(): invalid next size (fast): 0x0000000001747340

code snippet:

  id3tag = new_tag();

  if (strlen(artist) > 0) {
    tag_set_artist (artist, 0, id3tag);
    }
  if (strlen(title) > 0) {
    tag_set_title (title, 0, id3tag);
    }
  if (strlen(album) > 0) {
    tag_set_album (album, 0, id3tag);
    }
  if (strlen(tracknum) > 0) {
    tag_set_track (tracknum, 0, id3tag);
    }
  if (strlen(date) > 0) {
    tag_set_year (date, 0, id3tag);
    }
  if (strlen(genre) > 0) {
    tag_set_genre (genre, 0, id3tag);
    }
  if (strlen(comment) > 0) {
    tag_set_comment (comment, 0, id3tag);
    }

set_tag ("test", id3tag);

error message:

*** Error in `./wave-add-id3-tag': free(): invalid next size (fast): 0x0000000001747340 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x6e88f)[0x7fa44206288f]
/lib64/libc.so.6(+0x785de)[0x7fa44206c5de]
/lib64/libc.so.6(+0x792b7)[0x7fa44206d2b7]
/usr/lib64/libid3v2.so.0(set_comment_frame+0xd1)[0x7fa4423a0053]
/usr/lib64/libid3v2.so.0(tag_set_comment+0x6f)[0x7fa4423a0533]
./wave-add-id3-tag[0x40115b]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fa442015b15]
./wave-add-id3-tag[0x4009a9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 fe:06 156968873                          /mnt/quadrupole/afterBackup/00wave/wave-add-id3-tag
00601000-00602000 rw-p 00001000 fe:06 156968873                          /mnt/quadrupole/afterBackup/00wave/wave-add-id3-tag
01747000-01768000 rw-p 00000000 00:00 0                                  [heap]
7fa441dde000-7fa441df4000 r-xp 00000000 fe:01 208172                     /usr/lib64/libgcc_s.so.1
7fa441df4000-7fa441ff3000 ---p 00016000 fe:01 208172                     /usr/lib64/libgcc_s.so.1
7fa441ff3000-7fa441ff4000 rw-p 00015000 fe:01 208172                     /usr/lib64/libgcc_s.so.1
7fa441ff4000-7fa442193000 r-xp 00000000 fe:01 2252819                    /lib64/libc-2.18.so
7fa442193000-7fa442393000 ---p 0019f000 fe:01 2252819                    /lib64/libc-2.18.so
7fa442393000-7fa442397000 r--p 0019f000 fe:01 2252819                    /lib64/libc-2.18.so
7fa442397000-7fa442399000 rw-p 001a3000 fe:01 2252819                    /lib64/libc-2.18.so
7fa442399000-7fa44239d000 rw-p 00000000 00:00 0
7fa44239d000-7fa4423a2000 r-xp 00000000 fe:01 205728                     /usr/lib64/libid3v2.so.0
7fa4423a2000-7fa4425a1000 ---p 00005000 fe:01 205728                     /usr/lib64/libid3v2.so.0
7fa4425a1000-7fa4425a2000 rw-p 00004000 fe:01 205728                     /usr/lib64/libid3v2.so.0
7fa4425a2000-7fa4425c2000 r-xp 00000000 fe:01 2252825                    /lib64/ld-2.18.so
7fa442781000-7fa442784000 rw-p 00000000 00:00 0
7fa4427be000-7fa4427c1000 rw-p 00000000 00:00 0
7fa4427c1000-7fa4427c2000 r--p 0001f000 fe:01 2252825                    /lib64/ld-2.18.so
7fa4427c2000-7fa4427c3000 rw-p 00020000 fe:01 2252825                    /lib64/ld-2.18.so
7fa4427c3000-7fa4427c4000 rw-p 00000000 00:00 0
7fff981ac000-7fff981cd000 rw-p 00000000 00:00 0                          [stack]
7fff981ff000-7fff98200000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

Compile error using clang on Debian bullseye Arm machine.

file_functions.c:138:10: warning: implicit declaration of function 'ID3v2_tag_new' is invalid in C99 [-Wimplicit-function-declaration] tag = ID3v2_tag_new(); ^ file_functions.c:138:8: warning: incompatible integer to pointer conversion assigning to 'ID3v2_Tag *' (aka 'struct _ID3v2_Tag *') from 'int' [-Wint-conversion] tag = ID3v2_tag_new(); ^ ~~~~~~~~~~~~~~~ 2 warnings generated. /usr/bin/ld: /tmp/file_functions-695003.o: in function tagger':
file_functions.c:(.text+0x718): undefined reference to ID3v2_read_tag' /usr/bin/ld: file_functions.c:(.text+0x728): undefined reference to ID3v2_tag_new'
/usr/bin/ld: file_functions.c:(.text+0x768): undefined reference to ID3v2_to_unicode' /usr/bin/ld: file_functions.c:(.text+0x77c): undefined reference to ID3v2_Tag_set_album_artist'
/usr/bin/ld: file_functions.c:(.text+0x790): undefined reference to ID3v2_to_unicode' /usr/bin/ld: file_functions.c:(.text+0x7a4): undefined reference to ID3v2_Tag_set_track'
/usr/bin/ld: file_functions.c:(.text+0x7bc): undefined reference to ID3v2_to_unicode' /usr/bin/ld: file_functions.c:(.text+0x7d0): undefined reference to ID3v2_Tag_set_album'
/usr/bin/ld: file_functions.c:(.text+0x7e4): undefined reference to ID3v2_to_unicode' /usr/bin/ld: file_functions.c:(.text+0x7f8): undefined reference to ID3v2_Tag_set_title'
/usr/bin/ld: file_functions.c:(.text+0x80c): undefined reference to ID3v2_to_unicode' /usr/bin/ld: file_functions.c:(.text+0x820): undefined reference to ID3v2_Tag_set_artist'
/usr/bin/ld: file_functions.c:(.text+0x838): undefined reference to ID3v2_write_tag' clang: error: linker command failed with exit code 1 (use -v to see invocation)
Let me know if you need any more information. I also tried compiling using gcc and got very similar errors.

Unicode string termination issues

When I read the tags that have unicode text in them, in most cases there's some garbage before string termination character.

Example:

Byte sequence I get:
ff fe 32 00 30 00 31 00 35 00 31 0c f7 7f 00 00

"Corrected" byte order before I decode it from UTF-16:
fe ff 00 32 00 30 00 31 00 35 0c 31 7f f7 00 00

What I get:
2015ఱ翷

So, "fe ff" is a BOM, "00 32 00 30 00 31 00 35" is "2015". Then there are four garbage bytes "0c 31 7f f7" followed by string termination. Those garbage bytes are different every time I run the app, so looks like RAM garbage rather than something existing in the mp3 file. Also, those files' metadata displays correctly in other apps.

Here's what different "size" values say.

frame->header->size: 17
textFrame->data->size: 16
ID3v2_strlen: 14
ID3v2_strlent: 16

Correct length, if we count BOM and termination bytes should be 8 + 2 for BOM + 2 for terminations, equals 12. So all those values above are off.

Here's a bit of code I'm doing:

// I'm iterating through all the tags.
// At this point of code I'm sure I'm looking at Text frame, so I just cast it below.

juce::String value;  // I'm using this type externally, don't worry too much about it
ID3v2_TextFrame* textFrame = (ID3v2_TextFrame*)frame;
const char encoding = textFrame->data->encoding;

/*
I also try frame->header->size and textFrame->size.
All three of them are different values, but the actual readable section of the text is shorter that them.
*/
const int textLengthBytes = ID3v2_strlent (textFrame->data->text);

if (encoding == ID3v2_ENCODING_ISO)
{
    // ISO encoding, keeping it as is
    value = juce::String (textFrame->data->text, textLengthBytes);
}
else if (encoding == ID3v2_ENCODING_UNICODE)
{
    // UNICODE - this is where the trouble is

    DBG ("frame->header->size: " << frame->header->size);
    DBG ("textFrame->size: " << textFrame->size);

    // I'm printing those bytes here to see what's under the hood
    DBG ("====");
    for (int i = 0; i < textLengthBytes; ++i)
        DBG (static_cast<unsigned char> (textFrame->data->text[i]));
    DBG ("====");

    // This but makes sure bytes are in correct order and interprets them as UTF16
    // I've used other means of converting, same result, so I don't think the issue is here
    const auto* textAsUnicode = reinterpret_cast<juce::CharPointer_UTF16::CharType*> (textFrame->data->text);
    juce::CharPointer_UTF16 textAsUnicodeCharPointer (textAsUnicode);
    value = juce::String (textAsUnicodeCharPointer);
}

Also worth mentioning that I build the project using VS v143, but I've compiled your library using LLVM (clang) since it has Variable length arrays that aren't supported by VS. Either there's some incompatibility between binaries, or I'm missing something else there.

If you think my compiler setup is to blame, I can volunteer to fix #48 and replace those VLA's by malloc's, so I can build everything via VS toolset.

`TagHeader_free` is private.

TagHeader_free doesn't seem to be part of the public interface, but there are public functions which return ID3v2_TagHeader*, so it probably should be made part of the public interface or removed entirely in favour of free (which it wraps) to avoid misleading people.

dll needed for id3v2lib

I need a dll for the id3v2lib project so that I can access the functions from an application. Can you point me to instructions on how to do that? It would be nice to have the build procedure for id3v2lib also build a dll.

itob memory leak

The following code can be seen inside itob:
char* result = (char*) malloc(sizeof(char) * size);

This result buffer is never freed in any subsequent calls and thus repeated calling of itob would cause a memory leak of 4 bytes

ID3 v1

Would I be wasting my time if I added support for ID3 v1, v1.1, and Extended v1 tags?

On windows, in order to open file name with other language

I added the following util method and replace all fopen with this:
#ifdef _WINDOWS
#include <Windows.h>
#endif

FILE* tag_openFile(const char* filename, const char* mode)
{
#ifdef _WINDOWS
WCHAR nameBuffer[256];
memset(nameBuffer, 0, 2562);
MultiByteToWideChar(CP_UTF8, 0, filename, -1, nameBuffer, 256
2);
WCHAR modeBuffer[256];
memset(modeBuffer, 0, 2562);
MultiByteToWideChar(CP_UTF8, 0, mode, -1, modeBuffer, 256
2);
return _wfopen(nameBuffer, modeBuffer);
#else
return fopen(filename, mode);
#endif
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.