diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..8dc6807 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,21 @@ +{ + "rules": { + "no-console": "off", + "indent": [ "error", 2 ], + "quotes": [ "error", "single" ], + "semi": ["error", "always"], + "linebreak-style": [ "error", "unix" ] + }, + "env": { + "es6": true, + "node": true, + "mocha": true, + "jasmine": true + }, + "ecmaFeatures": { + "modules": true, + "experimentalObjectRestSpread": true, + "impliedStrict": true + }, + "extends": "eslint:recommended" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0992345 --- /dev/null +++ b/.gitignore @@ -0,0 +1,117 @@ +# Created by https://www.gitignore.io/api/node,vim,osx,macos,linux + +*node_modules + +### Node ### +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + + + +### Vim ### +# swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-v][a-z] +[._]sw[a-p] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags + + +### OSX ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon +# Thumbnails +._* +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + +### macOS ### +# Icon must end with two \r +# Thumbnails +# Files that might appear in the root of a volume +# Directories potentially created on remote AFP share + + +### Linux ### + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# End of https://www.gitignore.io/api/node,vim,osx,macos,linux diff --git a/bitmap-annashivwill/.eslintrc b/bitmap-annashivwill/.eslintrc new file mode 100644 index 0000000..8dc6807 --- /dev/null +++ b/bitmap-annashivwill/.eslintrc @@ -0,0 +1,21 @@ +{ + "rules": { + "no-console": "off", + "indent": [ "error", 2 ], + "quotes": [ "error", "single" ], + "semi": ["error", "always"], + "linebreak-style": [ "error", "unix" ] + }, + "env": { + "es6": true, + "node": true, + "mocha": true, + "jasmine": true + }, + "ecmaFeatures": { + "modules": true, + "experimentalObjectRestSpread": true, + "impliedStrict": true + }, + "extends": "eslint:recommended" +} diff --git a/bitmap-annashivwill/.gitignore b/bitmap-annashivwill/.gitignore new file mode 100644 index 0000000..0992345 --- /dev/null +++ b/bitmap-annashivwill/.gitignore @@ -0,0 +1,117 @@ +# Created by https://www.gitignore.io/api/node,vim,osx,macos,linux + +*node_modules + +### Node ### +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + + + +### Vim ### +# swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-v][a-z] +[._]sw[a-p] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags + + +### OSX ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon +# Thumbnails +._* +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + +### macOS ### +# Icon must end with two \r +# Thumbnails +# Files that might appear in the root of a volume +# Directories potentially created on remote AFP share + + +### Linux ### + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# End of https://www.gitignore.io/api/node,vim,osx,macos,linux diff --git a/bitmap-annashivwill/README.md b/bitmap-annashivwill/README.md new file mode 100644 index 0000000..fd37a07 --- /dev/null +++ b/bitmap-annashivwill/README.md @@ -0,0 +1,41 @@ +![CF](https://camo.githubusercontent.com/70edab54bba80edb7493cad3135e9606781cbb6b/687474703a2f2f692e696d6775722e636f6d2f377635415363382e706e67) Lab 04: Bitmap Transformer +=== + +## To Submit this Assignment +* have team leader fork this repository +* have team leader add team members as collaborators to the team fork +* team members should clone team fork +* write all of your code in a directory name `bitmap-` + `` **e.g.** `bitmap-weasels` +* submit a pull request to this repository when done +* each person will submit a link to their own PR in canvas +* each person write a question and observation on canvas + +#### Rubric: +* **tests:** 3pts +* **gulpfile/package.json:** 2pts +* **read bitmap meta data:** 5pts +* **successfully apply transforms:** 5pts +* **project design and organization:** 5pts + +## Description + +For this assignment you will be building a bitmap (`.bmp`) reader and transformer. It will read a bitmap in from disk, run one or more color transforms on the bitmap and then write it out to a new file. This project will require the use of node buffers in order to manipulate binary data. Your project should include tests, as well as a `gulpfile.js`, `package.json`, `.eslintrc`, `README.md`, and a `.gitignore`. Make sure to run all your code through eslint. The process will look something like this: + +1. open the original bitmap file using fs and read it into a buffer +2. convert the buffer header data into a Javascript Object (using constructors) +3. run a transform on the buffer directly +4. write the buffer to a new file + +The wikipedia article found here [Bitmap Specification](https://en.wikipedia.org/wiki/BMP_file_format) describes the byte specification of a "windows bitmap file." We'll be working with the simplest version, meaning no compression. + +* your project should have three ***(or more)*** transforms +* invert the colors (***hint:*** subtract every color value from the max color value which is 255), +* grayscale the colors (***hint:*** multiply each color value by a constant, just make sure your values don't go over 255) +* (red|green|blue)scale the colors (***hint:*** same as above but only multiply one of the colors) + +## Bonus: + +* ability to handle various sized bitmap +* ability to handle LE and BE computers with a single if statement +* utilizes a command line interface (CLI) +* CLI can select the transforms diff --git a/bitmap-annashivwill/img/black.bmp b/bitmap-annashivwill/img/black.bmp new file mode 100644 index 0000000..248db67 Binary files /dev/null and b/bitmap-annashivwill/img/black.bmp differ diff --git a/bitmap-annashivwill/img/grey.bmp b/bitmap-annashivwill/img/grey.bmp new file mode 100644 index 0000000..7d7e1f8 Binary files /dev/null and b/bitmap-annashivwill/img/grey.bmp differ diff --git a/bitmap-annashivwill/img/inverted.bmp b/bitmap-annashivwill/img/inverted.bmp new file mode 100644 index 0000000..5cfbdac Binary files /dev/null and b/bitmap-annashivwill/img/inverted.bmp differ diff --git a/bitmap-annashivwill/img/palette-bitmap.bmp b/bitmap-annashivwill/img/palette-bitmap.bmp new file mode 100644 index 0000000..97ad0df Binary files /dev/null and b/bitmap-annashivwill/img/palette-bitmap.bmp differ diff --git a/bitmap-annashivwill/img/red.bmp b/bitmap-annashivwill/img/red.bmp new file mode 100644 index 0000000..823860d Binary files /dev/null and b/bitmap-annashivwill/img/red.bmp differ diff --git a/bitmap-annashivwill/index.js b/bitmap-annashivwill/index.js new file mode 100644 index 0000000..9f3f415 --- /dev/null +++ b/bitmap-annashivwill/index.js @@ -0,0 +1,6 @@ +'use strict'; + +const maps = require(`${__dirname}/model/read-write.js`); +const transforms = require(`${__dirname}/lib/transforms.js`); + +maps.readWrite(); diff --git a/bitmap-annashivwill/lib/file-reader.js b/bitmap-annashivwill/lib/file-reader.js new file mode 100644 index 0000000..6e938c1 --- /dev/null +++ b/bitmap-annashivwill/lib/file-reader.js @@ -0,0 +1,10 @@ +'use strict'; + +const fs = require('fs'); + +const fileReader = module.exports = function(file, callback) { + fs.readFile(file, function(err, data) { + if (err) return callback(err); + return callback(null, data); + }) +} diff --git a/bitmap-annashivwill/lib/transforms.js b/bitmap-annashivwill/lib/transforms.js new file mode 100644 index 0000000..86dcfe3 --- /dev/null +++ b/bitmap-annashivwill/lib/transforms.js @@ -0,0 +1,41 @@ +'use strict'; + +const fs = require('fs'); +const image = require(`${__dirname}/../index.js`); + +module.exports = exports = {}; + +exports.turnBlack = function(bitmap) { + const blackBuf = new Buffer(bitmap); + return blackBuf.fill('00', 54, 1078); + // console.log(blackBuf); +}; + +exports.invert = function(bitmap) { + const invertBuf = new Buffer(bitmap); + for (var i = 54; i < 1078; i++) { + invertBuf.fill(255-bitmap[i], i, i+1); + }; + // console.log(invertBuf.toString('hex').slice(54,1078)); + return invertBuf; +}; + +exports.redScale = function(bitmap) { + const redBuf = new Buffer(bitmap); + for(var i = 56; i < 1078; i += 4) { + redBuf.fill(255, i, i+1); + }; + // console.log(redBuf.toString('hex').slice(54,1078)); + return redBuf; +}; + +exports.greyScale = function(bitmap) { + const greyBuf = new Buffer(bitmap); + for(var i = 54; i < 1078; i += 4) { + greyBuf.fill(greyBuf[i+1], i, i+1); + greyBuf.fill(greyBuf[i+1], i+1, i+2); + greyBuf.fill(greyBuf[i+1], i+2, i+3); + }; + // console.log(greyBuf.toString('hex').slice(54,1078)); + return greyBuf; +}; diff --git a/bitmap-annashivwill/model/read-write.js b/bitmap-annashivwill/model/read-write.js new file mode 100644 index 0000000..daa2122 --- /dev/null +++ b/bitmap-annashivwill/model/read-write.js @@ -0,0 +1,36 @@ +'use strict'; + +const fs = require('fs'); +const transforms = require(`${__dirname}/../lib/transforms.js`); + +module.exports = exports = {}; +// +// const file1 = `${__dirname}/../img/palette-bitmap.bmp`; +// const file2 = `${__dirname}/../img/inverted.bmp`; +// const file3 = `${__dirname}/../img/black.bmp`; +// const file4 = `${__dirname}/../img/red.bmp`; +// const file5 = `${__dirname}/../img/grey.bmp`; + +exports.readWrite = function() { + + fs.readFile(`${__dirname}/../img/palette-bitmap.bmp`, function(err, data) { + if (err) throw err; + const bitmap = data; + + fs.writeFile(`${__dirname}/../img/inverted.bmp`, transforms.invert(bitmap), function(err, data) { + if (err) throw err; + }); + + fs.writeFile(`${__dirname}/../img/black.bmp`, transforms.turnBlack(bitmap), function(err, data) { + if (err) throw err; + }); + + fs.writeFile(`${__dirname}/../img/red.bmp`, transforms.redScale(bitmap), function(err, data) { + if (err) throw err; + }); + + fs.writeFile(`${__dirname}/../img/grey.bmp`, transforms.greyScale(bitmap), function(err, data) { + if (err) throw err; + }); + }); +}; diff --git a/bitmap-annashivwill/package.json b/bitmap-annashivwill/package.json new file mode 100644 index 0000000..a434667 --- /dev/null +++ b/bitmap-annashivwill/package.json @@ -0,0 +1,20 @@ +{ + "name": "bitmap-annashivwill", + "version": "1.0.0", + "description": "![CF](https://camo.githubusercontent.com/70edab54bba80edb7493cad3135e9606781cbb6b/687474703a2f2f692e696d6775722e636f6d2f377635415363382e706e67) Lab 04: Bitmap Transformer\r ===", + "main": "index.js", + "directories": { + "test": "test" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "chai": "^3.5.0", + "gulp": "^3.9.1", + "mocha": "^3.2.0" + } +} diff --git a/bitmap-annashivwill/test/additional-tests.js b/bitmap-annashivwill/test/additional-tests.js new file mode 100644 index 0000000..eb83ad5 --- /dev/null +++ b/bitmap-annashivwill/test/additional-tests.js @@ -0,0 +1,144 @@ +'use strict'; + +const expect = require('chai').expect; +const fileReader = require('../lib/file-reader.js'); + +////////// TESTS ////////// + +///// REIVING BITMAP TESTS ///// +describe('RECEIVING BITMAP MODULE --', function() { + describe('Should return a failed test:', function() { + it('for incorrect or nonexistant bitmap filepath.', function(done) { + fileReader(`${__dirname}/../notreal.js`, function(err) { + expect(err).to.be.an('error'); + done(); + }); + }); + }); + describe('Should return a passing test:', function() { + it ('for correct original bitmap filepath.', function(done) { + fileReader(`${__dirname}/../img/palette-bitmap.bmp`, function(err, data) { + expect(err).to.equal(null); + expect(data.toString('hex')).to.be.a('string'); + done(); + }); + }); + }); +}); + +///// BLACK TRANSFORMATION TESTS ////// +describe('BLACK TRANSFORMATION MODULE --', function() { + describe('Should return a failed test:', function() { + it('for incorrect filepath of BLACK.', function(done) { + fileReader(`${__dirname}/../img/notblack.bmp`, function(err) { + expect(err).to.be.an('error'); + done(); + }); + }); + }); + describe('Should return a passing test:', function() { + it('for the correct transformation of BLACK.', function(done) { + fileReader(`${__dirname}/../img/black.bmp`, function(err, data) { + expect(err).to.equal(null); + // expect(data.toString()).to.be.a('string'); + expect(data.toString('utf-8').slice(54, 1078)).to.equal('0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + done(); + }); + }); + }); +}); + +///// INVERSE TRANSFORMATION TESTS ///// +describe('INVERSE TRANSFORM MODULE --', function() { + describe('Should return a failed test:', function() { + it('for incorrect filepath of INVERSE.', function(done) { + fileReader(`${__dirname}/../img/notinverted.bmp`, function(err) { + expect(err).to.be.an('error'); + done(); + }); + }); + }); + describe('Should return a passing test:', function() { + it('for the correct transformation of INVERSE.', function(done) { + fileReader(`${__dirname}/../img/inverted.bmp`, function(err, data) { + expect(err).to.equal(null); + // expect(data.toString('hex')).to.be.a('string'); + expect(data.toString('hex').slice(54, 1078)).to.equal('0008000000000010270000120b0000120b00000001000000010000ffffffffcbdfddffc3d7baffcec699ffc4a970ffd98e20ff995f26ff653c11ffc90d04ffaf1a66ffcf4195ff916bc8ffd096b4ffdbb4adffc6c3cdff8bc0c0ff7d9fcfff1e91a4ff00649cff1b32a0ff032434ff000000ff485264ff78817bff959596ffada9a6ff75bd89ffcdcd53ff9ca826ff458428ffb56870ffcf9075ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'); + done(); + }); + }); + }); +}); + +///// REDSCALE TRANSFORMATION TESTS ///// +describe('RED TRANSFORMATION MODULE --', function() { + describe('Should return a failed test:', function() { + it('for incorrect filepath of REDSCALE.', function(done) { + fileReader(`${__dirname}/../img/notred.bmp`, function(err) { + expect(err).to.be.an('error'); + done(); + }); + }); + }); + describe('Should return a passing test:', function() { + it('for correct transformation of REDSCALE.', function(done) { + fileReader(`${__dirname}/../img/red.bmp`, function(err, data) { + expect(null).to.equal(null); + // expect(data.toString('hex')).to.be.a('string'); + expect(data.toString('hex').slice(54, 1078)).to.equal('0008000000000010270000120b0000120b000000010000000100000000ff003420ff003c28ff003139ff003b56ff002671ff0066a0ff009ac3ff0036f2ff0050e5ff0030beff006e94ff002f69ff00244bff00393cff00743fff008260ff00e16eff00ff9bff00e4cdff00fcdbff00ffffff00b7adff00877eff006a6aff005256ff008a42ff003232ff006357ff00ba7bff004a97ff00306fff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000000ff0000'); + done(); + }); + }); + }); +}); + + +///// GREYSCALE TRANSFORMATION TESTS ///// +describe('GREYSCALE TRANSFORMATION MODULE --', function() { + describe('Should return a failed test:', function() { + it('for incorrect filepath of GREYSCALE.', function(done) { + fileReader(`${__dirname}/../img/notgrey.bmp`, function(err) { + expect(err).to.be.an('error'); + done(); + }); + }); + }); + describe('Should return a passing test:', function() { + it('for the correct transformation for GREYSCALE.', function(done) { + fileReader(`${__dirname}/../img/grey.bmp`, function(err, data) { + expect(err).to.equal(null); + // expect(data.toString('hex')).to.be.a('string'); + expect(data.toString('hex').slice(54, 1078)).to.equal('0008000000000010270000120b0000120b00000001000000010000000000002020200028282800393939005656560071717100a0a0a000c3c3c300f2f2f200e5e5e500bebebe0094949400696969004b4b4b003c3c3c003f3f3f00606060006e6e6e009b9b9b00cdcdcd00dbdbdb00ffffff00adadad007e7e7e006a6a6a00565656004242420032323200575757007b7b7b00979797006f6f6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'); + done(); + }); + }); + }); +}); + + +// //shouldBeGrey: +// originalMapString = bitmap.toString(54, 1078); +// if originalMapString.match(/(\d+)\1+\1+/g).length === 256 +// + + +// +// describe('Buffer Color Palette Conversion Module', function() { +// describe('Test for successful inverse conversion', function(done) { +// it('which should pass if the color has changed correctly', function(err, data) { +// }); +// }); +// }); + + // + // shouldBeInvert = `${}` + // shouldBeRed = str.match(/255[^255]*/g).length = 256 + // shouldBeGrey = str.match(/(\d+)\1+\1+/g).length = 256; + // + // //reverse string d.split('').reverse().join('') Can the same be done on buffer? + // + // describe('Testing Module Transforms', function() { + // describe('turnBlack switches palette to black', function() { + // it('') + // }); + // });