Giter Site home page Giter Site logo

c2pa-rs's People

Contributors

brogdonm avatar christianpaquin avatar crandmck avatar dependabot[bot] avatar dkozma avatar duggaraju avatar dyro avatar emensch avatar gpeacock avatar jackfarzan avatar keisss avatar mauricefisher64 avatar mklein13 avatar ok-nick avatar raymurillo avatar scouten-adobe avatar yannbonnemay 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

c2pa-rs's Issues

Duplication of code in store.rs with slightly different behaviors.

There is lot of duplication across the various functions like

start_save() vs start_save_stream()
finish_save() vs finish_save_stream() finsh_save_to_memory()

and the corresponding jumbf versions .
If they can be combined or refactored to reuse the same code then that would avoid duplication and make it easy to test or even support signing bmff files from a memory buffer etc.

Self-signed ECDSA certificate is not accepted

out

Attached file is failing with "explanation": "certificate params incorrect", but I'm not clear why that is

  • it's an EC key using prime256v1, self-signed with SHA256+ECDSA
  • the public key parameters are set (I assume, from the message, that this is the failure, but as it's just the curve I can't see how)
  • keyUsage and extendedKeyUsage are both set
  • it has no AuthorityKeyIdentifier because it's self-signed

As far as I can see, other than being self-signed it's structurally identical to the key from truepic-20230212-library.jpg from the public repository

Suggestion: Document pitfall for Android usage

Android OS automatically redacts (replaces with 0) Geotags from Exif Data, unless the App has requested the ACCESS_MEDIA_LOCATION permission. This behavior is documented here.

This resulted in the Hashes not matching on Android, while the same image validated successfully on a Mac. It took a lot of debugging to find, because the last thing we expected was Android silently modifying the files content upon reading.

I would like to suggest adding this piece of information to an FAQ/Pitfalls section to help out others who might want to use this SDK on Android.

c2pa-rs incorrectly rejecting self-signed certificates

Originally submitted as an issue to c2patool: contentauth/c2patool#152 but this looks like a bug in c2pa-rs.

c2patool cannot be used with self-signed certs because c2pa-rs rejects self-signed certs.

As noted by Leszko in contentauth/c2patool#114, the c2pa-rs source code is written to explicitly forbid self-signed certs. (

if is_self_signed {
)

This contradicts the C2PA specification, which repeatedly mentions the use of self-signed certificates:
https://c2pa.org/specifications/specifications/1.2/specs/C2PA_Specification.html#_x_509_certificates
E.g.,

  • "The presence of a self-signed certificate in the parameter MUST NOT cause the update of the set of trust anchors without some out-of-band confirmation." (permits self-signed)
  • "The Authority Key Identifier extension must be present in any certificate that is not self-signed." (permits self-signed)

If you comment out the check/rejection of self-signed certs in the c2pa-rs code, then it correctly accepts self-signed certs. However, nobody else using c2patool will be able to validate it unless they apply the same patch.

Either c2pa-rs needs to be corrected to permit self-signed certs, or the C2PA specification needs to be updated to forbid self-signed certs.

Validation and c2pa.placed

Cross-posted from the Discord group. I'm not quite sure where to put these, as I think they're issues with the test files as well as issues with the API.

There are two public files from https://github.com/c2pa-org/public-testfiles/tree/main/image that c2patool says are valid, but I'm not so sure:

adobe-20220124-CICACACA.jpg

The active manifest ends in 8a8f462cb30d: the "c2pa.actions" assertion, fourth action is "c2pa.placed"but has no parameters, so no url:

            {
              "action": "c2pa.placed",
              "instanceId": "xmp:iid:a649c709-5c9f-47a7-aa1d-850b26789d62"
            },

But 18.10 says

c2pa.placed" action "shall" have parameters

and 15.7.3 point a.iii.A.I.1 says this is an assertion.action.ingredientMismatch

adobe-20220124-CAIAIIICAICIICAIICICA.jpg

The active manifest ends in 065a84099cc7: the "c2pa.actions" assertion fourth action is "c2pa.placed" and refers to "c2pa.ingredient", which has a relationship of "parentOf"

            {
              "action": "c2pa.placed",
              "instanceId": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb",
              "parameters": {
                "ingredient": {
                  "hash": "tTBD4/E0R0AjLUdJFpsVz3lE/KJUq22Vz0UGqzhEpVs=",
                  "url": "self#jumbf=c2pa.assertions/c2pa.ingredient"
                }
              }
            },

...

        "c2pa.ingredient": {
          "dc:format": "image/jpeg",
          "dc:title": "A.jpg",
          "documentID": "xmp.did:813ee422-9736-4cdc-9be6-4e35ed8e41cb",
          "instanceID": "xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb",
          "relationship": "parentOf",
          "thumbnail": {
            "hash": "z55bRqFSv/HdQlFpU96AUPwDnHMWi/XVVanedKE7kxc=",
            "url": "self#jumbf=c2pa.assertions/c2pa.thumbnail.ingredient.jpeg"
          }
        },

But again in 15.7.3 it says:

For c2pa.placed or c2pa.removed: Check that the value of the relationship field is componentOf. If it is not, the claim must be rejected with a failure code of assertion.action.ingredientMismatch.

Add support for other certificate information in `certificate_info` field

We do the x.509 parsing in c2pa-rs and right now we will capture the data for the name of an organization, however not personal info if the certificate was set up in a non-organizational manner. This will add support for those other fields so we can display them in downstream projects/SDKs.

GJSS TEST ISSUE #2 JIRA TO GITHUB EXPORT

  • Description:

  • Steps to reproduce:

  • Observed result:

  • Expected result:

  • Workaround:

  • Reproducible rate: 100%; intermittent; random:

  • Platform & Version: Mac or Win:

  • Browser (if applicable):

  • Plugin Build#: if applicable, and/or Ps Build #:

  • Regression? (Yes/No). If "Yes", provide the last passed build info:

  • Attach screenshot of issue and/or problematic image with Content Credentials

Bad example in Crate docs, `from_file` not implemented in ManifestStore

Hi, while going through the example in https://docs.rs/c2pa/latest/c2pa/#example-reading-a-manifeststore
Am getting not implemented error (E0599)

error[E0599]: no function or associated item named `from_file` found for struct `ManifestStore` in the current scope
 --> src/main.rs:4:41
  |
4 |     let manifest_store = ManifestStore::from_file("tests/fixtures/C.jpg")?;
  |                                         ^^^^^^^^^ function or associated item not found in `ManifestStore`

My cargo.toml file

[dependencies]
c2pa = "0.11.0"

Add support for Ed25519 in Wasm

The C2PA 1.0 spec outlines support for three digital signature algorithms, with one being Ed25519. We are not supporting this at the moment in Web Assembly since Web Crypto doesn't have support for this. However, the RustCrypto org has published a crate that provides Ed25519 support in pure Rust, which we should be able to use for this.

`cargo run --example client` failed

When I ran cargo run --example client, I ran into the following errors:

$ cargo run --example client 
   Compiling c2pa v0.7.0 (/home/ec2-user/workspace/c2pa-rs/sdk)
    Finished dev [unoptimized + debuginfo] target(s) in 6.86s
     Running `target/debug/examples/client`
Error: No such file or directory (os error 2)

After some debugging, it occurs to me it is related to the following two lines:

let signcert_path = "../sdk/tests/fixtures/certs.ps256.pem";
let pkey_path = "../sdk/tests/fixtures/certs.ps256.pub";

signcert_path should point to the certificate certs.ps256.pub while pkey_path should point to the private key certs.ps256.pem. That is, things should look like

    let signcert_path = "./sdk/tests/fixtures/certs/ps256.pub";
    let pkey_path = "./sdk/tests/fixtures/certs/ps256.pem";

Can`t verify generated images

Hello!

I tried to verify test image (attached to issue) generated by your`s library on this verification site. But it failed in case of unavailable image content credentials (screenshot attached bellow).
But image verified by c2pa-tool (v 0.2.0, from this project) successfully.
Could you say what side is getting wrong: verification site or this project?

CAI
cai_verify

Suggestion: Add examples in README for basic use cases

From yong2023 via Discord:

I think it will be helpful to add in README on how to add credential to an image, then how to show the credentials.

I know this by asking my friends and try myself and finally using the command in Makefile and change the input image in it with my own. Something like:

"cargo run --example client ~/Desktop/Hepburn3.jpg target/tmp/client.jpg"

Then use make show or cargo run --example show -- target/tmp/client.jpg to show the credential

also can go to verify page at: https://verify.contentauthenticity.org/inspect to show the credentials added

C2PA-rs returns wrong validation code for box hash failure

C2PA-rs returns validation code assertion.dataHash.mismatch for a box hash failure instead of assertion.boxesHash.mismatch.

The C2PATool v 0.6.2 returns

    {
      "code": "assertion.**dataHash**.mismatch",
      "url": "self#jumbf=/c2pa/urn:uuid:c1ff5172-2367-4fa0-9f4c-f6e8710900f6/c2pa.assertions/c2pa.hash.boxes",
      "explanation": "asset hash error: hash verification( Box hash name not found )"
    }

instead of

    {
      "code": "assertion.**boxesHash**.mismatch",
      "url": "self#jumbf=/c2pa/urn:uuid:c1ff5172-2367-4fa0-9f4c-f6e8710900f6/c2pa.assertions/c2pa.hash.boxes",
      "explanation": "asset hash error: hash verification( Box hash name not found )"
    }

In addition to this change, for boxes hashes success, C2PA is adding the assertion.boxesHash.match success code in the next version to match the other hard binding success codes.

Request: Generalize support for a remote manifest store URI reference

I've been working through the SDK and understanding the layout as well as learning the C2PA specification, so please bear with me if I misunderstand any of the fundamentals or fumble with the terminology.

From what I have observed, the start_save function in the store module writes a manifest store, a reference URI to a manifest store, or both to an asset. Due to the use of the embedded_xmp module, it's currently tied to embedding a remote manifest store URI to specific file formats like JPEG and PNG, which support XMP, limiting its reusability.

To address this, the embedding of remote manifest store URIs could be abstracted into a separate trait that defines methods for writing asset references. This approach is similar to defining IO traits in the asset_io module. I think this would also start to move in the right direction of supporting remote references for streaming (i.e. start_save_stream) assets too. For example, could have a ManifestUriRef trait defined in asset_io:

/// Interface for supporting a URI reference to an active manifest.
pub trait ManifestUriRef {
    /// Add the URI for the active manifest for the file.
    /// 
    /// ## Arguments
    /// - `asset_path`: Path to the asset to add the URI reference to
    /// - `manifest_uri`: A valid URI to the active manifest
    fn add_manifest_uri_to_file(&self, asset_path: &Path, manifest_uri: &str) -> Result<()>; 

    /// Removes the URI for the active manifest for the file.
    /// 
    /// ## Arguments
    /// - `asset_path`: Path to the asset to add the URI reference to
    fn remove_manifest_uri_from_file(&self, asset_path: &Path) -> Result<()>;
}

pub fn get_manifest_ref(ext: &str) -> Result<Box<dyn ManifestUriRef>> {
    let ext = ext.to_ascii_lowercase();
    match ext.as_ref() {
        "jpg" | "jpeg" => Ok(Box::new(JpegIO {})),
        "png" => Ok(Box::new(PngIO{})),
        "tif" | "tiff" | "dng" => Ok(Box::new(TiffIO{})),
        _ => Err(crate::error::Error::RemoteManifestNotSupported),
    }
}

The embedded_xmp functionality can then be implemented as a concrete implementation of the trait for image file formats like JPEG and PNG. This would make the start_save function more flexible and modular, enabling it to work with various file formats. For example the JpegIO struct could implement as follows:

impl ManifestUriRef for JpegIO {
    fn add_manifest_uri_to_file(&self, asset_path: &Path, manifest_uri: &str) -> Result<()> {
        #[cfg(feature="xmp_write")]
        {
            add_manifest_uri_to_file(asset_path, manifest_uri)
        }
        #[cfg(not(feature = "xmp_write"))]
        {
            Err(crate::error::Error::MissingFeature("xmp_write"))
        }
        
    }

    fn remove_manifest_uri_from_file(&self, _asset_path: &Path) -> Result<()> {
        todo!()
    }
}

This would allow for the store::start_save to write the remote reference cleaner:

crate::claim::RemoteManifest::EmbedWithRemote(_url) => {
    get_manifest_ref(&ext)?.add_manifest_uri_to_file(dest_path, &_url)?;
    dest_path.to_path_buf()
}

Overall, the point is abstracting this part of the code would improve code maintainability and extensibility by separating concerns and enabling reuse of functionality. The sample code provided was just to provide context, there may be a better way to implement said suggestions.

APP11 already has data

Hi, we have encountered bug where photos from one of our devices can´t be used by c2pa. We use c2pa rust sdk and we tested this photo with c2pa tool both reported same error and it is "not found". After closer look at other images this image has already some data written into app11 segment they are just "00 00" but other images has app11 completly empty we asume this might be the problematic area. When we strip all metadata from photo then we are able to use both our program and c2pa tool with no problem but stripping the metadata should not be needed and is not expected for proper functionality of c2pa sdk.

the problematic photo

20230102_152829 (1)

the valid photo where problems dont ocure

20230112_105622

as seen here the problematic photo has app11 data (the left one)

image

we tried it with

c2patool 20230102_152829.jpg -m test.json -o 20230102_152829.jpg -f
testing manifest is
{ "ta_url": "http://timestamp.digicert.com", "claim_generator": "TestApp", "assertions": [ { "label": "stds.schema-org.CreativeWork", "data": { "@context": "https://schema.org", "@type": "CreativeWork", "author": [ { "@type": "Person", "name": "Joe Bloggs" } ] } } ] }
We are certain that this problem should be handled inside rust sdk and not in our code as the library doesn´t state that this isnt valid picture. The code in our case crashes when we use manifest_store.embed(...) function and error state just not found with no helpful message or explanation
same error occurs in c2pa_tool
image

for more information please contact me i am able to share more if needed.

Remove dependency on twoway crate

Running cargo deny on this crate yields the following warning:

error[A003]: Crate `twoway` deprecated by the author
    ┌─ /.../c2pa-rs/Cargo.lock:223:1
    │
223 │ twoway 0.2.2 registry+https://github.com/rust-lang/crates.io-index
    │ ------------------------------------------------------------------ unmaintained advisory detected
    │
    = ID: RUSTSEC-2021-0146
    = Advisory: https://rustsec.org/advisories/RUSTSEC-2021-0146
    = The commit [`e99b3c7`](https://github.com/bluss/twoway/commit/e99b3c718df1117ad7f54c33f6540c8f46cc17dd) releasing version 0.2.2 explicitly deprecates `twoway` in favour of [`memchr`](https://crates.io/crates/memchr) crate.
    = Announcement: https://github.com/bluss/twoway
    = Solution: No safe upgrade is available!
    = twoway v0.2.2
      ├── c2pa v0.20.0
      │   └── make_test_images v0.20.0
      └── make_test_images v0.20.0 (*)

Rust SDK doc comments

Re <https://opensource.contentauthenticity.org/docs/rust-sdk/]

  • The docs should focus more on how to use the SDK as it is now. It's OK to note key features that are NYI, but for details link to the release notes. [THIS IS DONE>
  • API docs have two examples: "Reading a ManifestStore" and "Adding a Manifest to a file" which have only code, and no explanation. These would be better elsewhere in the docs, with some explication. Keep them in the API docs, if that makes sense, but also put them in task sections.

Failed reading with JumbfParseError

The image below fails to read in c2patool with the following output

c2patool --info out.jpg 
[2023-02-23T17:39:43Z DEBUG c2pa::ingredient] ingredient "out.jpg"
[2023-02-23T17:39:43Z DEBUG c2pa::ingredient] ingredient JumbfParseError(UnexpectedEof)
Information for out.jpg
No C2PA Manifests

This is created by another C2PA API which is still under development - so I'm certainly open to the fact that the C2PA is genuinely invalid.

However the app11 marker is accepted (by jpegtran etc) and the JUMBF box hierarchy is tested by both our code (it's also a verifier, so has been run on all the public C2PA samples) and also loads without error in https://github.com/thorfdbg/codestream-parser. So I'm fairly confident at this point.

SHA256 sum of this image is 4eef35e7becaf084c205fc962448327128f7ded053c987592b04f188f711fe1a, just in case it gets mangled by github - I posted the same to the CAI Discord server, and it was certainly mangled there.

out

MP3 support

Is version 0.29 on the main branch? The readme indicates its from Nov 2023, but I'm trying to use c2patool on mp3s but keep getting an error "XMP is not supported" even though I specified to use c2pa-rs main branch in the dependencies.

EDIT: More specifically, what I'm trying to do is to embed a remote manifest url on an mp3, without remote manifests it works.

CBOR generated by `test_build_assertion` may be invalid

I saved a copy of the CBOR generated in one of our tests (see https://github.com/contentauth/c2pa-rs/blob/main/sdk/src/assertions/actions.rs#L450).

It contains several (hex) ef bf bd sequences which do not make sense as initial values in CBOR:

  • ef = major type 7, minor value 15, which is unassigned
  • bf = major type 5 (map), indefinite length, which is legal
  • bd = major type 5 (map), minor value 29, which would be legal, but there are not 29 key/value pairs in the subsequent data

This file also is rejected by the third-party cbor-diag parser.

Explain how to perform key tasks

The existing doc doesn't have much other than some basic overview info and API doc.

The docs should explain (for example) how to:

  • Display C2PA data on your site or app - Leverage the bare-bones example in "Reading a ManifestStore" in API docs?
  • Link C2PA data displayed on your site to Verify
  • Write C2PA data into files - Leverage bare-bones example in "Adding a Manifest to a file" in API docs?
  • Quickly create and inspect C2PA data
  • Customize displaying and creating C2PA data
  • Deploy on Web, mobile, and desktop

Suggestion: Add troubleshooting FAQ for build issues

From yong2023 via Discord:

To me, I first faced an Caused by: failed to load source for dependency async-trait issue, and the reason was my cargo version too low. So I need run rustup update stable to update my rustc and cargo to latest version. (edited)

Also I run xcode-select --install and softwareupdate –install -a to upgrade my clang version on Macbook

and finally add exports in .bash_profile

All these can save a lot of time for newbies like me.

GJSS TEST ISSUE #2 JIRA TO GITHUB EXPORT

  • Description:

  • Steps to reproduce:

  • Observed result:

  • Expected result:

  • Workaround:

  • Reproducible rate: 100%; intermittent; random:

  • Platform & Version: Mac or Win:

  • Browser (if applicable):

  • Plugin Build#: if applicable, and/or Ps Build #:

  • Regression? (Yes/No). If "Yes", provide the last passed build info:

  • Attach screenshot of issue and/or problematic image with Content Credentials

Return additional information in the explanation about the box hash failure.

It would be nice to get more details on the failures.

1st example "Box hash name not found" would be better if it was like "Box hash name, SOS, not found in the file."

2nd example: "Hashes do not match" would be better if it was "Hash for box RST1, yy8dviSIFeUgM7C96eAiygJ8T0hjQcjhLGl0Xy0o9Fo=, does not match expected hash, nDOggBltZJSdQGLPSgrdqmeS7y69QOazEcpWJfTwmWk="

Digest for Manifest referenced from ingredient doesn't compute.

There are a number of files in https://github.com/c2pa-org/public-testfiles/tree/main/image that refer to the manifest contentauth:urn:uuid:04cdf4ec-f713-4e47-a8d6-7af56501ce4b (CA.jpg) as an ingredient.

For example, here's an excerpt from the C2PA object in
https://github.com/c2pa-org/public-testfiles/blob/main/image/jpeg/adobe-20220124-CA.jpg

"c2pa.ingredient": {
    "c2pa_manifest": {
        "alg": "sha256",
        "hash": "3epjVN8X1spZW0Z6TYQO/6owR7xADaDDVzeeDBOGV4g=",
        "url": "self#jumbf=/c2pa/contentauth:urn:uuid:04cdf4ec-f713-4e47-a8d6-7af56501ce4b"
     },

In all cases that same hash is used, which is base64(3epjVN8X1spZW0Z6TYQO/6owR7xADaDDVzeeDBOGV4g=) or hex(ddea6354df17d6ca595b467a4d840effaa3047bc400da0c357379e0c13865788).

My problem is I can't match that to the manifest.

I'm fully aware of the digest algorithm described in https://c2pa.org/specifications/specifications/1.2/specs/C2PA_Specification.html#_hashing_jumbf_boxes

When creating a URI reference to an assertion (i.e., as part of constructing a Claim), a W3C Verifiable Credential or other C2PA structure stored as a JUMBF box, the hash shall be performed over the contents of the structure’s JUMBF superbox, which includes both the JUMBF Description Box and all content boxes therein (but does not include the structure’s JUMBF superbox header).

That's what I'm doing, and it's matching perfectly the output from c2patool for all JUMBF box types - except manifests.

In desperation I have even tried digesting various byte ranges from the C2PA object directly at to try and find one that matches that digest - none do. There is no byte-range in the C2PA object that matches that SHA-256 digest (edit: see next comment), which surely means there must be some special processing for manifest boxes going on.

The digest I am expecting is base64(4h9T1UCSjePpgfwJddVkegL4vFKX5qRj5UYaNtTB0jA=) or hex(e21f53d540928de3e981fc0975d5647a02f8bc5297e6a463e5461a36d4c1d230), which matches the 126477 bytes starting at byte 46 of the C2PA. Here is the C2PA object I am testing, extracted from adobe-20220124-CA.jpg: extracted-c2pa.zip

So I suppose I have two questions as a result:

  1. is there some special processing for manifest boxes?
  2. or, failing that, would it be possible to get a dump of the bytes used to generate that digest, and I can try and figure out what's going on from there.

Finally, below is the file I am trying to verify with (what I think is) the correct digest for that manifest, which is failing to verify in c2patool. It is just a repackaging of adobe-20220124-CA.jpg

repackaged

GJSS TEST ISSUE #2 JIRA TO GITHUB EXPORT

  • Description:

  • Steps to reproduce:

  • Observed result:

  • Expected result:

  • Workaround:

  • Reproducible rate: 100%; intermittent; random:

  • Platform & Version: Mac or Win:

  • Browser (if applicable):

  • Plugin Build#: if applicable, and/or Ps Build #:

  • Regression? (Yes/No). If "Yes", provide the last passed build info:

  • Attach screenshot of issue and/or problematic image with Content Credentials

Abstract use of instance/document IDs and provenance for ingredient use

Currently, the SDK relies on assets to support XMP to properly be an ingredient. Since not all assets support XMP, would be beneficial to abstract this behavior, to allow for:

  • Optional method for getting a new ID to use for instance/document ID

    This would allow an asset to provide a customized ID instead of one with xmp:*

  • Setting an instance/document ID when signing an asset the first time
  • Getting an instance/document ID from an asset
  • Getting the provenance URI of a remote manifest

The ingredient.rs mod would be able to utilize these new methods to build out the ingredient information and would appropriately support remote manifests.

fix compatibility for is_parent and deprecate it.

When loading an ingredient the default is to add relationship: "componentOf". This has the effect of override an is_parent: true flag in an ingredient. For better backwards compatibility we should automatically set a "parentOf" relationship if an is_parent flag exists and is set to true. At that same time, we should deprecate is_parent, so developers are warned to move away from it and use relationship instead.

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.